17

I have a very big draggable div in my window. This div has a smaller window.

<div id="draggable-area" style="width:500px;height:500px;overflow:hidden">
 <div id="draggable" style="width:5000px;height:5000px">
     <ul>
         <li></li>
         <li></li>
         <li></li>
         <li></li>
         <li></li>
         ....
     </ul>
  </div>
</div>  

How can I know if the li element is visible in the user viewport (I mean really visible, not in the overflow area)?

gung - Reinstate Monica
  • 10,603
  • 7
  • 53
  • 74
Sebastien
  • 6,490
  • 14
  • 52
  • 101
  • Is this the same as the question that was asked here? http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling – Anderson Green Mar 31 '13 at 21:30

6 Answers6

24

To check if an element is in the current veiwport:

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}

(Source)

For a more robust method, I'd recommend Viewport Selectors, which allow you to just do:

$("#elem:in-viewport")
Community
  • 1
  • 1
Alex Peattie
  • 23,394
  • 5
  • 46
  • 51
22

have a look at this plugin

It give's you the option to do the following selectors

$(":in-viewport")
$(":below-the-fold")
$(":above-the-top")
$(":left-of-screen")
$(":right-of-screen")
Manuel van Rijn
  • 9,800
  • 1
  • 24
  • 49
1

https://github.com/sakabako/scrollMonitor

var scrollMonitor = require("./scrollMonitor"); // if you're not using require, you can use the scrollMonitor global.
var myElement = document.getElementById("itemToWatch");

var elementWatcher = scrollMonitor.create( myElement );

elementWatcher.enterViewport(function() {
    console.log( 'I have entered the viewport' );
});
elementWatcher.exitViewport(function() {
    console.log( 'I have left the viewport' );
});

elementWatcher.isInViewport - true if any part of the element is visible, false if not.
elementWatcher.isFullyInViewport - true if the entire element is visible [1].
elementWatcher.isAboveViewport - true if any part of the element is above the viewport.
elementWatcher.isBelowViewport - true if any part of the element is below the viewport.
trushkevich
  • 2,578
  • 1
  • 25
  • 34
0

I m using (checks whether an element is at least partially in the view) following code:

var winSize;

function getWindowSize() {
            var winW,WinH = 0;
            if (document.body && document.body.offsetWidth) {
                winW = document.body.offsetWidth;
                winH = document.body.offsetHeight;
            }
            if (document.compatMode == 'CSS1Compat' &&
                document.documentElement &&
                document.documentElement.offsetWidth) {
                winW = document.documentElement.offsetWidth;
                winH = document.documentElement.offsetHeight;
            }
            if (window.innerWidth && window.innerHeight) {
                winW = window.innerWidth;
                winH = window.innerHeight;
            }
            return {w:winW, h:winH};
        }

winSize = getWindowSize();    

function inView(element) {
                var box = element.getBoundingClientRect();
                if ((box.bottom < 0) || (box.top > winSize.h)){
                    return false;
                }
                return true;
            }
Lumic
  • 43
  • 2
0

For a more up-to-date way using getBoundingClientRect():

var isInViewport = function (elem) {
    var bounding = elem.getBoundingClientRect();
    return (
        bounding.top >= 0 &&
        bounding.left >= 0 &&
        bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
};

Returns true if the element in completely in the viewport, and false if it’s not.

var myElem = document.querySelector('#draggable');
if (isInViewport(myElem)) {
    // Do something...
}

Complete explanation found here.

Maze
  • 1
  • 1
0

My solution is using the given code example, and it will show you an overall idea of how to determine whether the li element is visible. Check out the jsFiddle which contains code from your question.

The jQuery .offset() method allows us to retrieve the current position of an element relative to the document. If you click on an li element inside the draggable, your offset from the top will be between 0 and 500 and the offset from the left should be between 0 and 500. If you call the offset function of an item that is not currently visible, the offset will either be less than 0 or greater than 500 from either the top or left offset.

If its not a daunting task I always like to code what I need from 'scrath' it gives me more flexibility when having to modify or debug, hence why I would recommend looking into using jQuery's offset function instead of using a plugin. If what you are trying to accomplish is fairly simple, using your own function will give you one less library to load.

Jose Vega
  • 9,800
  • 7
  • 37
  • 56