how to implement infinite scrolling using native javascript and yui3 ?
Hi all, recently I had an opportunity to solve an interesting problem of implementing "infinite scrolling" or "continuous scrolling" or "endless scrolling" using native javascript and yui3. While I thought there was an existing solution for this problem, all of the solutions were pointing to jquery and none were using native javascript/yui3. Hence, I implemented a solution to solve the problem stated using native javascript and yui3.
Notes
As of Jan 2019, there are better ways of implementing infinite scrolling feature. Please refer to https://infinite-scroll.com or https://jscroll.com if you want updated code. The following still holds good conceptually.
Fundamental concept
I will use the below diagram to explain you certain basics about various heights within a webpage and after this solid foundation we will see how to use this in achieving infinite scrolling.
pageHeight - This is the overall page height. This is the max height you can scroll. This can be accessed using document.documentElement.scrollHeight.
scrollPos - This is the current scroll bar position. This is accessed using document.documentElement.scrollTop in Internet Explorer and window.pageYOffset in Firefox, Chrome, Opera, Apple and other browsers.
clientHeight - This is the remaining height that the scroll bar can be scrolled to reach its maximum position, i.e, pageHeight. It can be accessed via document.documentElement.clientHeight.
Now that you know the above 3 heights, let us chalk the criteria for infinite scrolling. We want to initiate an update to fetch more items that will be concatenated to the page when the scrollbar is 50px above its max height. If we write a small algorithm for the same, it will be as below.
Algorithm
Check if (pageHeight - (scrollPos + clientHeight) < 50) is true whenever onscroll event is generated on the window.
If the above is true, initiate an update and prevent requests for further updates until the response arrives.
Update the page if the response is positive else handle error scenarios.
Fetching top RSS stories from YQL
To supply input to the page, I will use YQL to fetch top RSS stories. It can be accessed directly using YQL RSS Query.
|
https://query.yahooapis.com/v1/public/yql?q=select title,link,pubDate from rss where url='http://rss.news.yahoo.com/rss/topstories'
|
Since I want to paginate the results, I will pass two additional parameters namely "limit" i.e., number of articles to fetch at a time and "offset" that indicates the index offset to user when fetching further items.
Without digging into details, I directly curl the above api endpoint, parse the result and then generate markup. I also added some CSS to make it look prettier.
Curl the YQL API endpoint
Markup generation
Finishing touch
The heart of the hack - Javascript part
I will use YUI3 library to make the ajax part easy. Let's instantiate a YUI3 instance in which we will use "node", "event" and "io-base" modules. We also need to call function "handleScroll" whenever an onscroll event is generated. I assign a local variable self to this in order to avoid scope issues. I'll need to write a detailed post on how we bypass scoping issues by assigning "this" to "self, hence I advise you to look up good javascript books (Definitive Guide or Good Parts) to understand this concept. You can also achieve similar functionality by using anonymous/self-referencing functions.
Instantiating YUI3 and calling handleScroll
Please note that we also initialized the pagination unit (this.offset) and updateInitiated flag (to disable further requests until response arrives). I also use retries, maxRetries and allStoriesFetched flag for error handling scenarios.
Checking the condition and initiating an AJAX request followed by update
Notes
Here we check the condition (pageHeight - (scrollPos + clientHeight) < 50) is true or not. If yes, we check that there are less than 200 items on the page and no previous update has already been initiated.
If all the conditions are satisfied, we initiate an AJAX request via Y.io. You can read up more details about how to achieve AJAX via YUI3 at http://yuilibrary.com/yui/docs/io/.
We reset the updateInitiated flag once we receive the response and we also update the pagination unit i.e., offset by 10 if the response received is a set of items and concatenate it to the existing list of items. (Pagination Unit (offset) is not updated in case of failure).
Once we reach 200 items, we stop the infinite scrolling... i.e, we make it finite :) ! You can continue forever though :D !
Putting it to together
If we integrate the above mentioned PHP script and Javascript with some CSS and loading gif images, we achieve the Infinite Scrolling. You can find the complete source code @ Infinte-Scroll-SourceCode.
Comments
Comments powered by Disqus