Book Image

HTML5 Data and Services Cookbook

Book Image

HTML5 Data and Services Cookbook

Overview of this book

HTML5 is everywhere. From PCs to tablets to smartphones and even TVs, the web is the most ubiquitous application platform and information medium bar. Its becoming a first class citizen in established operating systems such as Microsoft Windows 8 as well as the primary platform of new operating systems such as Google Chrome OS. "HTML5 Data and Services Cookbook" contains over 100 recipes explaining how to utilize modern features and techniques when building websites or web applications. This book will help you to explore the full power of HTML5 - from number rounding to advanced graphics to real-time data binding. "HTML5 Data and Services Cookbook" starts with the display of text and related data. Then you will be guided through graphs and animated visualizations followed by input and input controls. Data serialization, validation and communication with the server as well as modern frameworks with advanced features like automatic data binding and server communication will also be covered in detail.This book covers a fast track into new libraries and features that are part of HTML5!
Table of Contents (21 chapters)
HTML5 Data and Services Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Creating an endless scrolling list


Endless scrolling lists were popularized by social networking websites, such as Facebook and Twitter. Their goal is to create the illusion that the entire available content has already been loaded. Additionally, with this technique, interruptions to the normal scrolling that are caused by the user trying to find the button for the next page are avoided.

At the same time, we would also want to avoid unnecessary waste of bandwidth; this means that loading the whole set of data at once is not an option.

The solution is to monitor the user's scrolling and detect the approach at the bottom of the page. When the user is sufficiently close to the bottom, we can automatically load the next page of content by appending it to the end of the currently shown content.

Getting ready

You must already have a service that provides the content on a page-by-page basis. This example works without such a service by default, but to make it fully functional, an actual HTTP server is needed in order for the Ajax requests for the next page to work.

How to do it...

Let's write the HTML page, CSS style, and JavaScript code.

  1. Create a file named index.html that will contain the full HTML, CSS, and JavaScript code of our example. We need to insert a DOCTYPE into our HTML document; otherwise, the browser will operate in "quirks mode" and the height measurement function $(window).height() will not work.

    <!DOCTYPE HTML>

    We'll add a content placeholder element in the page:

    <div id="content"></div>
  2. For demonstration purposes, we'll add the following CSS code to make the pages visible. Feel free to skip this CSS:

    div.page {
       min-height: 1200px;
       width: 800px;
       background-color:#f1f1f1;
       margin:0.3em;
       font-size: 3em;
    }
    div.error {
       color:#f00;
    }
  3. Finally, we add the JavaScript code. First we load jQuery:

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
    </script>

    Then we can add our script:

    <script type="text/javascript">
    (function() {

    Our page getter calls the callback with a null error argument and a simple string containing the page number as the content (for example, Page 1), but it can also perform an Ajax request. See the following code for more info on how to modify it to make an Ajax request.

    This function is artificially limited to 10 pages of content. After the tenth page, the callback function is called with an error, indicating that there are no more pages available:

    var page = 1;
    function getPage(callback) {
       if (page <= 10)
           callback(null, 'Page ' + page);
       else
           callback("No more pages");
       page += 1;
    };
  4. We use triggerPxFromBottom to specify when to start loading the next page. When only triggerPxFromBottom pixels remain to be scrolled, the loading of the next page will begin. Its value is set to 0; this means that the user must reach the end of the currently visible page to trigger the loading process:

    var currentlyLoading = false;
    var triggerPxFromBottom = 0;
  5. loadNext appends the next page into the #content div. However, if the callback function is called with an error, it will display No more content below the last part of the page. After an error event, no more pages will be loaded. This means that when getPage returns an error, our code will stop loading new pages. This is the desired behavior:

    function loadNext() {
       currentlyLoading = true;
       getPage(function(err, html) {
            if (err) {
                $("<div />")
                    .addClass('error')
                    .html("No more content")
                    .appendTo("#content");
            } else {
                $("<div />")
                    .addClass('page')
                    .html(html).appendTo("#content");
                currentlyLoading = false;
            }
          });
    }
  6. This event handler is called when the page is scrolled in any way. It calculates the number of pixels of scrolling that remain below. If the number of the pixels is small enough and the code is not currently loading a page, it calls the page-loading function:

    $(window).on('scroll', function() {
        var remainingPx = $(document).height()
            - $(window).scrollTop()
            - $(window).height();
        if (remainingPx <= triggerPxFromBottom
            && !currentlyLoading)
            loadNext();
    });
  7. Finally, we call loadNext() for the first time to load the first page:

    loadNext();
    }());
    </script>

How it works...

The visible area of the browser (also called the viewport) has its own dimensions that can be fetched by calling jQuery's $.fn.height() function on the $(window) object. On the other hand, $(document).height() provides us with the height of the entire content of the page. Finally, $(window).scrollTop() gives us the scroll offset.

Using these functions, we can calculate the remaining pixels to be scrolled. Then we recalculate and check this value every time the user scrolls the page. If the value is sufficiently small, we call our loading function. At the same time, we make sure to stop loading new pages until the current loading process is finished. (Otherwise, the user's scrolling actions might load a couple of more pages while they wait for the content to load.)

There's more...

Here is a possible Ajax implementation of the getPage function. This function sends Ajax requests to a request handler hosted on the same domain at the path /pages/<number> to retrieve the HTML contents of the next page:

function getPage(cb) {
    $.get('/pages/' + page)
        .success(function(html) { cb(null, html); })
        .error(function() { cb("Error"); }
    page += 1;
}

To make this version work, you will need to implement the request handler in your server-side code.

Your server-side code can return an error, such as 404, to indicate that there is no more content available. As a result, jQuery will never call our success callback, and our code will stop loading new pages.

The endless scrolling list recipe provides great user experience, but it has one significant drawback. We must make sure that we don't have any important page content below the contents element. This means that page elements placed at the bottom (usually the footer links and copyright messages) might become unreachable.