views:

9447

answers:

6

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?

EDIT: freakytard solution was right, but I modified it a bit to also check if element is wholly visible

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

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

    return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
      && (elemBottom <= docViewBottom) &&  (elemTop >= docViewTop) );
}
+1  A: 

Hi,

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.

romaintaz
For some reason document.body.scrollTop always returns 0 (on ff3). Change it to var visibleTop = (document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop);
yoavf
Sorry for that. My application must run only in IE 6 (yes, I am not lucky :( ), so I never tested this in FF...
romaintaz
+4  A: 

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();
    });
};
Jonathan Sampson
+17  A: 

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 >= docViewTop) && (elemTop <= docViewBottom));
}
Scott Dowding
This function works great as intended (if the element is visible). If you want to make sure the element is entirely visible in the pain, you can simply change the return to:return ((docViewTop < elTop)
Nic
Of course... I meant the pane.
Nic
A: 

Hello,

this works fine for elements that are "totally" not in the wisible part of the window. For half seen elements, the function returns true where I would expect it to return false. Any idea what to change to have it return false in that case?

+1  A: 
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));
}
Pascal Gagneur
+3  A: 

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.

Joe Lencioni
Looks like the project has moved: http://code.google.com/p/jquery-appear/
Derrick