Implementing Infinite Scroll in jQuery

Shaumik Daityari
Tweet

For as long as I can remember, web developers have turned to good old fashioned pagination when there is a lot of content to show. Don’t get me wrong, pagination is still a very effective way of displaying content, but, in this post, we will discuss an alternative – infinite scroll. This technique, also known as lazy scroll or unpaginate, loads new content via Ajax when the user has finished scrolling through the page’s existing content. Infinite scrolling is used by some of the biggest names on the Internet, including Facebook and Pinterest. In this post, we will talk about building your own jQuery plugin to implement infinite scroll.

Tradeoffs

The advantages are obvious. To get more content, you don’t need to be redirected to a new page (which has a tendency to shift your focus to a different area while the page is loading). By implementing infinite scroll, you are basically controlling the user’s focus on the page!

Infinite scroll is not effective in all situations. For example, if a user clicks a link and then uses the browser’s Back button, the user loses his/her position in the stream of data that was loaded over Ajax. One precaution while implementing this feature is to load new content on a new tab or window.

A related drawback of infinite scrolling is its inability to save the position on the stream. Suppose you want to share something on a infinite scroll page with your friend via email. You are unable to do so because the URL takes you back to the initial position. Therefore, before you decide to go ahead with it, think about the usability of your website.

Additionally, before you implement infinite scrolling, remember that it’s not very search engine friendly. To avoid any issues with respect to visibility on search engines, make sure you provide an alternative with pagination or a sitemap.

Getting Started

We’ll begin by laying out a very simple page. The important parts of the example HTML and CSS are shown below. The remainder of the files can be seen by clicking on the demo link at the end of this tutorial.

HTML

<div id="data-container">
  <div class="data-item">
    Hi! I am the first item.
  </div>
  <div class="data-item">
    Hi! I am the second item.
  </div>
  <div class="data-item">
    Hi! I am the third item.
  </div>
  <div class="data-item">
    Ok, this is getting boring.
  </div>
  <div class="data-item">
    Let's try something new.
  </div>
  <div class="data-item">
    How about loading some more items through AJAX?
  </div>
  <div class="data-item">
    Click the button below to load more items.
  </div>
</div>
<div id="button-more" onclick="lazyload.load()">
  Load more items
</div>
<div id="loading-div">
  loading more items
</div>

CSS

#data-container {
  margin: 10px;
}

#data-container .data-item {
  background-color: #444444;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  padding: 5px;
  margin: 5px;
  color: #fff;
}

#loading-div {
  display: none;
}

#button-more{
  cursor: pointer;
  margin: 0 auto;
  background-color: #aeaeae;
  color: #fff;
  width: 200px;
  height: 50px;
  line-height: 50px;
}

Basic Workflow

If you have a look at the document that we’ve created, new posts should be loaded when you click on the “load more” button. Here are a few points to consider.

  • A request needs to be made to a URL which returns the new items to be appended to your page.
  • This process should repeat if the button is clicked again, but newer posts should be returned the second time.
  • New posts should be provided at every subsequent request, until there are no more posts to show.
  • When there are no more posts left, you should tell the user that he has reached the end.

Ajax Pattern

Ideally, you must declare a variable to store the page number, which in turn changes the URL to send the request to. In our demo, we have three such pages – 2.html, 3.html, and an empty 4.html for demonstration purposes.

When you click on the button to load more posts, there is some time before the request goes through successfully and new items are loaded. In this case, we hide the load button, and show some text saying that the new items are being loaded:

$(buttonId).hide();
$(loadingId).show();

Appending Data to the Page

First, we need to undo the changes that we performed when the request was in progress, namely, showing the “load more” button again and hiding the text. Secondly, we need to append the response that we received to the list of items already present on the page. Note that in the demo, we receive HTML markup directly to keep things simple. You can send a JSON response too, adding more variables like a message or a status. The append code is shown below.

$(buttonId).show();
$(loadingId).hide();
$(response).appendTo($(container));
page += 1;

Handling End of Data

Once you reach the end of your posts, you need to show your user that there are no more posts to load on the page. This can be done in many ways. We can send the status through a code or message embedded within the response itself. However, as we use HTML markup directly in this example, an empty response marks the end of the stream.

$.ajax({
...
  success: function(response) {
    // What to do if the response is empty
    if (response.trim() == "") {
      $(buttonId).fadeOut();
      $(loadingId).text("No more entries to load!");
      return;
    }
    // Do something if the response is right.
  },
...
});

Conclusion

The demo that we have come up with is very basic in nature, and we can do far better if we put in some more effort. First, we can remove the button altogether and call the function when the user scrolls down to the end of the page. This would remove an extra step of the user clicking the button and make the whole process faster. Secondly, we can just send the raw data through JSON and create the markup using jQuery itself. For example:

$.each(response.items, function(index, value) {
  $("<div />", {
    "class" : "data-item",
    "text" : value
  });
});

Finally, the JSON response could consist of a message stating whether the request went through correctly, the data, and whether there are more posts to load. This is a more efficient way of sending a response in this case.

For more information on infinite scroll, you could visit this website dedicated to the cause. It contains general information about the idea and existing tools that you can use to implement it in your website.

A live demo can be found on GitHub pages. The code is also available on GitHub.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Roman

    What’s the effect of this method on SEO?

    • http://twitter.com/clamiax Claudio

      The same as any content loaded via AJAX, which is not seen by crawlers.

      • Roman

        The more sites use this technique, the better it will be for those that don’t.

        • Ralph Echter

          Most of the time this technique is used for content previews which will link to the definite article or post. As long as you generate with PHP an XML sitemap on the server which updates automatically when there is a new article added, then the article/post is indexed and reachable (for Google and Bing at least, but then you will have likely 90 percent of you search enigine traffic).
          The only thing that I think should be improved with infinite scrolling content is the user experience. Going back from an article/post to the page with the infinite scrolling content will bring you back at the start/top of the page again and not where user was the last time. So user have to scroll all the way over again.
          Perhaps combining the technique with pushstate (history api,) so that you change the url too when clicking for more content and back button will bring you back where you were?

          • http://shaumikthinks.blogspot.com/ Shaumik Daityari

            I agree that preserving the state is very important for user experience, especially when you want to share it.

  • Jingqi Xie

    Why not a template engine?

    • http://shaumikthinks.blogspot.com/ Shaumik Daityari

      Hi,

      You could definitely use one. There are many options for jQuery template engines. This was a very basic one too.

      Secondly, if you are using something like Django or Express, you may use their own template engines rather than a separate one for JavaScript.