jQuery infinite scrolling scrolling in fixed div


Background

I am trying to create an infinite scrolling table inside a fixed position div. The problem is that all the solutions I come across use the window height and document scrollTop to calculate if the user has scrolled to the bottom of the screen.

Problem

I have tried to create a jQuery plugin that can calculate if a user has scrolled to the bottom of a fixed div with overflow: scroll; set.

My approach has been to create a wrapper div (the div with a fixed position and overflow: scroll) that wraps the table, I also place another div at the bottom of the table. I then try calculate if the wrapper.scrollTop() is greater than the bottom div position.top every time the wrapper is scrolled. I then load the new records and append them to the table body.

$.fn.isScrolledTo = function () {
    var element = $(this);
    var bottom = element.find('.bottom');

    $(element).scroll(function () {
        if (element.scrollTop() >= bottom.position().top) {
            var tableBody = element.find("tbody");
            tableBody.append(tableBody.html());
        }
    });
};

$('.fixed').isScrolledTo();

See Example http://jsfiddle.net/leviputna/v4q3a/

Question

Clearly my current example is not correct. My question is how to I detect when a user has scrolled to the bottom of a fixed div with overflow:scroll set?

Using the bottom element is a bit clunky, I think. Instead, why not use the scrollHeight and height to test once the scrollable area has run out.

$.fn.isScrolledTo = function () {

     var element = this,
         tableBody =  this.find("tbody");

     element.scroll(function(){
         if( element.scrollTop() >= element[0].scrollHeight-element.height()){
             tableBody.append(tableBody.html());
         }
     });

};

$('.fixed').isScrolledTo();

EDIT (12/30/14):

A DRYer version of the plugin might be much more re-usable:

$.fn.whenScrolledToBottom = function (cback_fxn) {
     this.on('scroll',this,function(){
         if( ev.data.scrollTop() >= ev.data[0].scrollHeight - ev.data.height()){
             return cback_fxn.apply(ev.data, arguments)
         }
     });
};

Plugin Usage:

var $fixed = $('.fixed'),
    $tableBody = $fixed.find("tbody");

$fixed.whenScrolledToBottom(function(){
    // Load more data..
    $tableBody.append($tableBody.html());
});

I have modified your code to handle the scroll event with a timer threshold:

 $.fn.isScrolledTo = function () {
     var element = $(this);
     var bottom = element.find('.bottom');


     $(element).scroll(function(){
        if (this.timer) clearTimeout(this.timer);
         this.timer=setTimeout(function(){
         if( element.scrollTop() >= bottom.position().top){
             var tableBody =  element.find("tbody");
             tableBody.append(tableBody.html());
         }
         },300);
     });


};

$('.fixed').isScrolledTo();

The issue you are having is that as you scroll, new scroll event is being generated. Your code might have other issues, but this is a start.