Tuesday, September 1, 2015

INFINITE SCROLLING IN Jquery

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.




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?


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.


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);
    }
}

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.

$(document).on("scrollstop", checkScroll);

Popular Posts