Check if element is visible after scrolling

0 votes
asked Jan 28, 2009 by yoavf

I'm loading elements via AJAX. Some of them are only visible if you scroll down the page.
Is there any way I can know if an element is now in the visible part of the page?

29 Answers

0 votes
answered Jan 9, 2009 by pascal-gagneur
function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop(),
        docViewBottom = docViewTop + $(window).height(),
        elemTop = $(elem).offset().top,
     elemBottom = elemTop + $(elem).height();
   //Is more than half of the element visible
   return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}
0 votes
answered Jan 28, 2009 by romaintaz

I have such a method in my application, but it does not use jQuery:

/* Get the TOP position of a given element. */
function getPositionTop(element){
    var offset = 0;
    while(element) {
        offset += element["offsetTop"];
        element = element.offsetParent;
    }
    return offset;
}

/* Is a given element is visible or not? */
function isElementVisible(eltId) {
    var elt = document.getElementById(eltId);
    if (!elt) {
        // Element not found.
        return false;
    }
    // Get the top and bottom position of the given element.
    var posTop = getPositionTop(elt);
    var posBottom = posTop + elt.offsetHeight;
    // Get the top and bottom position of the *visible* part of the window.
    var visibleTop = document.body.scrollTop;
    var visibleBottom = visibleTop + document.documentElement.offsetHeight;
    return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}

Edit : This method works well for I.E. (at least version 6). Read the comments for compatibility with FF.

0 votes
answered Jan 28, 2009 by sampson

WebResourcesDepot wrote a script to load while scrolling that uses jQuery some time ago. You can view their Live Demo Here. The beef of their functionality was this:

$(window).scroll(function(){
  if  ($(window).scrollTop() == $(document).height() - $(window).height()){
    lastAddedLiveFunc();
  }
});

function lastAddedLiveFunc() { 
  $('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
  $.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
    function(data){
        if (data != "") {
          $(".wrdLatest:last").after(data);         
        }
      $('div#lastPostsLoader').empty();
    });
};
0 votes
answered Jan 28, 2009 by scott-dowding

This should do the trick:

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Simple Utility Function This will allow you to call a utility function that accepts the element you're looking for and if you want the element to be fully in view or partially.

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

Usage

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
    console.log('in view');
} else {
    console.log('out of view');
}
0 votes
answered Jan 20, 2010 by joe-lencioni

The best method I have found so far is the jQuery appear plugin. Works like a charm.

Mimics a custom "appear" event, which fires when an element scrolls into view or otherwise becomes visible to the user.

$('#foo').appear(function() {
  $(this).text('Hello world');
});

This plugin can be used to prevent unnecessary requests for content that's hidden or outside the viewable area.

0 votes
answered Jan 4, 2011 by fedir

jQuery Waypoints plugin goes very nice here.

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

There are some examples on the site of the plugin.

0 votes
answered Jan 26, 2012 by ness-ee

There is a plugin for jQuery called inview which adds a new "inview" event.


Here is some code for a jQuery plugin that doesn't use events:

$.extend($.expr[':'],{
    inView: function(a) {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
            ot = $(a).offset().top,
            wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
        return ot > st && ($(a).height() + ot) < (st + wh);
    }
});

(function( $ ) {
    $.fn.inView = function() {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
        ot = $(this).offset().top,
        wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();

        return ot > st && ($(this).height() + ot) < (st + wh);
    };
})( jQuery );

I found this in a comment here ( http://remysharp.com/2009/01/26/element-in-view-event-plugin/ ) by a bloke called James

There is a rather nice example of this here (scroll down to the bottom):

http://www.bbc.co.uk/sport/0/olympics/2012/

I can't be 100% sure that the example uses the same code, but...

EDIT... I've also written an extension to the inview plugin called 'exitview' which fires an event when the element leaves the page. Anyone interested in the code can PM me, if that's possible.

0 votes
answered Jan 14, 2013 by samiya-akhtar

If you want to tweak this for scrolling item within another div,

function isScrolledIntoView (elem, divID) 

{

    var docViewTop = $('#' + divID).scrollTop();


    var docViewBottom = docViewTop + $('#' + divID).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 
}
0 votes
answered Jan 16, 2013 by evanmcd

Modified the accepted answer so that the element has to have it's display property set to something other than "none" to quality as visible.

function isScrolledIntoView(elem) {
   var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();
  var elemDisplayNotNone = $(elem).css("display") !== "none";

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
}
0 votes
answered Jan 23, 2013 by robert

isScrolledIntoView is a very needful function, so I tried it, it works for elements not heigher than the viewport, but if the element is bigger as the viewport it does not work. To fix this easily change the condition

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

to this:

return (docViewBottom >= elemTop && docViewTop <= elemBottom);

See demo here: http://jsfiddle.net/RRSmQ/

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...