Continuous scrolling is very interesting pattern. If I would have to describe it in short I would say that new items are being loaded while you scroll down the content. If this sounds odd to you, don't worry. I thought it is absolutely crazy when I first read about it. But I realized people are amazed by this pattern after my session "ASP.NET patterns for better user experience" on MSDN Day in May this year. And let me just say that this pattern is used on Google Reader and Dzone.
However, it is surprisingly that there is not much articles on how to do it in ASP.NET! Honestly, I found one good article Javascript Tutorial - Continuous Pagination that reveals some details (I apologize if I missed any article, so please let me know).
Definition... a kind of
When I searched for a definition I found it under two more names: "Continious Pagination" and "Infinite Scrolling". I couldn't agree with those names. First, this is not pagination - it is completely opposite pattern. While in pagination you click on a specific page to see some content, in Continuous scrolling you just scroll down and new content comes asynchronously. Second, I have a problem with the term infinite. It actually can't be infinite - eventually you'll come to an end of a content. So let's stick with the name "Continuous scrolling".
I already mentioned that this is an opposite pattern to a well known pagination. So, when to use it?
Like pagination, this pattern should be used when there is more data than can fit in a container. And that's the only similarity. The major difference between pagination and scrolling is that user can read the content without interruption. Without clicking on a page link and waiting for response. While scrolling down, the content is being automatically loaded and rendered. So reading can go swimmingly.
Implementation
Typically, user is notified that new content is being loaded by showing indicator in the bottom right angle of a content (as you can see on the screenshot on the left).
Generally, it looks like this: Initial content is loaded on the start. When user scrolls down to the end of the content, JavaScript function calls local WebService and a set of new items is sent back to the client.
Let's make an example. Since I use Google Reader every day, let's make something that looks like it. Ok, I admit, I stole colors for this example :)
This is going to be very simple. I have a list of countries stored in SQL database. Each country has ID, Name and number of Internet users. I would like to show the complete list in a div, and to enable continuous scrolling. Image on the left shows our example.
So, I will define CountryWS that will get the data from the database. This is the first catch and might be tricky. Since new data have to be loaded on request (precisely on scroll) I have to do paging in the database. I do that by sending two parameters to my stored procedure: PageIndex and PageSize. PageIndex will tell my stored procedure which page to query, and PageSize - how many items to retrieve.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class CountryWS : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod]
public List<Country> GetMoreCountries(int pageIndex, int pageSize)
{
System.Threading.Thread.Sleep(1000); SampleDAO sampleDAO = new SampleDAO();
List<Country> countries = sampleDAO.GetCountriesPaged(pageIndex, pageSize);
return countries;
}
}
That is "the server" part. Let's see what will happen on the client. All items will be rendered in a div that has onscroll handler defined.
<div id="content" runat="server" onscroll="OnDivScroll()">
<%--Items will be rendered here--%>
</div> OnDivScroll function will do a simple job - it will determine if the user scrolled down to the near bottom of the content. Then it will call CountryWS and pass the result to HandleRetrievedData function.
function OnDivScroll()
{
var content = document.getElementById('<%=content.ClientID %>');
if(content.scrollTop < content.scrollHeight - 500)
return; CountryWS.GetMoreCountriesObject(pageIndex, pageSize, HandleRetrievedData );
}
This is a second catch. Why near? The answer is simple - if you want your user to read smoothly, you'll have to load a new content BEFORE he/she reaches the end of the content. Ok?
And for the end, HandleRetrievedData function will parse the result and render new content.
function HandleRetrievedData(result)
{
var content = document.getElementById('<%=content.ClientID %>');
for (var i = 0; i <= result.length - 1; i++)
{
content.innerHTML += "<div class='entry'><b>" +
result[i].CountryName + "</b> (" + result[i].Symbol + ") - " +
result[i].InternetUsers + " internet user(s)</div>";
}
} You will notice that sample code is more complex than this example, but I will let you sweat a little bit ;)
Conclusion
You saw what Continuous scrolling is and how to easily implement it using JavaScript and ASP.NET. For more information about this pattern read Ajaxpatterns.org and Continuous Scrolling pattern on ui-patterns.com.
Don't forget to download the sample code!