Infinite Scrolling – Do It Yourself!


Update: Thanks to Brian for reporting an issue of multiple firing in Safari iOS. I have fixed this by removing the scrollstop listener when page bottom is reached and re-attaching it after loading more elements.

There are many handy third party plugins to handle infinite scrolling. They are meant to make your webapp lighter as not to load all contents at once. However, loading extra JavaScript libraries would affect the performance of a webapp negatively. Not to mention the bugs you might encounter or poor documentation. I never thought of creating such a tutorial of how to create your own infinite scroll until I found this post. I would like to also thank Mark for recommending my solution to be included in jQuery Mobile demo section.

Take a look at the following graph that illustrates the value we need to retrieve in order to determine whether the user has reached the bottom of the screen.

Infinite Scolling

What you need to know

We need to retrieve the following:

  • Content div’s height
  • Viewport’s height
  • Window’s scrollTop
  • Header’s height and whether it is fixed or not
  • Footer’s height and whether it is fixed or not

When does a user reach page’s bottom?

A simple equation..when Window’s scrollTop equals to or greater than (>=) Content div’s height minus (-) Viewport’s height plus (+) header & footer height.

We are 90% done by now, we just need to listen to a custom event called scrollstop to do our magic! This event fire when the user stops scrolling and it should be bound to document. The trick here is to determine in which page this event has been fired and whether you want to run any code on that page.

Let the Code speak and a Demo is worth a thousand words.

/* create scrollstop handler function */
function checkScroll() {
    /* You always need this in order to target
       elements within active page */
    var activePage = $.mobile.pageContainer.pagecontainer("getActivePage"),

        /* Viewport's height */
        screenHeight = $.mobile.getScreenHeight(),

        /* Content div - include padding too! */
        contentHeight = $(".ui-content", activePage).outerHeight(),

        /* Height of scrolled content (invisible) */
        scrolled = $(window).scrollTop(),

        /* Height of both Header & Footer and whether they are fixed
           If any of them is fixed, we will remove (1px)
           If not, outer height is what we need */
        header = $(".ui-header", activePage).outerHeight() - 1,
        footer = $(".ui-footer", activePage).outerHeight() - 1,

        /* Math 101 - Window's scrollTop should
           match content minus viewport plus toolbars */
        scrollEnd = contentHeight - screenHeight + header + footer;

    /* if (pageX) is active and page's bottom is reached
       load more elements  */
    if (activePage[0].id == "home" && scrolled >= scrollEnd) {
        /* run loadMore function */
        addMore(activePage);
    }
}

The trick to fix multiple firing is inside addMore() function. We first need to remove scrollstop listener, load more elements and then re-attached the listener.

function addMore(page) {
  /* remove scrollstop event listener */
  $(document).off("scrollstop");

  /* show loader (optional) */
  $.mobile.loading("show", {
    text: "loading more..",
    textVisible: true
  });

  /* delay loading elements 500ms
     and then re-attach scrollstop */
  setTimeout(function() {
    var items = '',
      last = $("li", page).length,
      cont = last + 5;
    for (var i = last; i < cont; i++) {
      items += "<li>" + i + "</li>";
    }
    $("#list", page).append(items).listview("refresh");
    $.mobile.loading("hide");

    /* re-attach scrollstop */
    $(document).on("scrollstop", checkScroll);
  }, 500);
}

Of course, don’t forget to attach scrollstop one time.

/* attach if scrollstop for first time */
$(document).on("scrollstop", checkScroll);

Buy Me A Coffee :) @ ko-fi.com

Advertisements

7 thoughts on “Infinite Scrolling – Do It Yourself!

  1. Pingback: INFINITE SCROLLING – DO IT YOURSELF! | Jquery Mobile
  2. Hi Malai,

    Thanks for your comment 🙂 Try disabling “click” on “scrollstart” and enable it on “scrollstop”.

    i.e.

    $("#listviewID").on("click", "li a", function () { 
       return false; 
    });
    
  3. Thanks for the lovely script.

    I load the list items using AJAX and I call ‘$(document).off(“scrollstop”);’ before the ‘$.ajax’ and call ‘$(document).on(“scrollstop”, checkScroll);’ inside the success function. The problem I face now is when I touch any of the listitem to scroll the page the touched listitem got selected (I.e, the checkbox in the list item got checked). I use phonegap and running on Android Lollipop Nexus 6 device. Any idea what could be the problem.

  4. Pingback: Articles updates | jQuery Mobile Tricks
  5. Hi Brian,

    This is true, it is happening in Safari (iPhone 5 iOS 8) but not in Chrome. I’ll dig more into this issue and will let you know.

    Thanks for reporting it 🙂

  6. Great post, clear explanation. Unfortunately, this method seems to be broken in iOS 8: The scrollstop event fires at least twice when you get to the bottom, sometimes more. I added an alert to the function to verify that it’s running multiple times with each scroll to the bottom. Any idea how to get around this?

Drop me a line or two ;)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s