2

I am trying to check if an element is inside my viewport when scrolling. If it is outside my viewport, I add a class that fixes the element to the top.

The function I use to determine if the element is outside the viewport is:

isElementInViewport : function(el) {
    //special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
    );
}

I added a scroll event which fires this function :

$(window).on('scroll', function(event){
   testObject.isElementInViewport(event.target);
}

The problem here is that while scrolling, my Lenovo Yoga's CPU goes crazy. I have tried:

  • polling with an interval
  • using a timeout function and a variable outside the event function scope to toggle on a certain interval

Both methods work, but I need a way to minimize performance impacts, because the page I use this in already has LOADS of JS working. I also need to fix the bar to top as soon as it gets outside the viewport and not a few milliseconds later.

Are there any low-performance solutions for this? Can this be done in CSS only?

Edit

I've noticed that I didn't asked my question right. The current answers below are working, but give the same HUGE performance impact when I scroll up and down a bit:

First answer Second answer

I need to prevent the script from needing so much CPU power!

PIDZB
  • 903
  • 1
  • 15
  • 38
  • `:visible` `css` selector will help you.. – Guruprasad J Rao May 04 '16 at 10:10
  • :visible is a jQuery selector, and it does not prevent me from having to check on a certain interval if the element is visible. The issue here is what kind of event/function to use to prevent the script from checking too much. – PIDZB May 04 '16 at 10:23
  • Its a `css` selector which could be used in `jquery` as `selector`.. But couldn't quite get your question well to my understanding.. – Guruprasad J Rao May 04 '16 at 10:24
  • i think this question will help you http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport – Ismail Farooq May 04 '16 at 10:28
  • and i also found this code http://jsfiddle.net/moagrius/wN7ah/ – Ismail Farooq May 04 '16 at 10:29

1 Answers1

0

copied from jQuery – test if element is in viewport (visible on screen)

HTML

<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box orange"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

JQuery

$.fn.isOnScreen = function() {
  var win = $(window);

  var viewport = {
    top: win.scrollTop(),
    left: win.scrollLeft()
  };
  viewport.right = viewport.left + win.width();
  viewport.bottom = viewport.top + win.height();

  var bounds = this.offset();
  bounds.right = bounds.left + this.outerWidth();
  bounds.bottom = bounds.top + this.outerHeight();

  return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));

};

$(window).scroll(function() {
  if ($('.orange').isOnScreen() === true) {
    console.log("Element is in viewport")
  }
});

Fidde

Ismail Farooq
  • 6,309
  • 1
  • 27
  • 47