Infinite scrolling using Javascript

A little how-to, mostly for myself, so I don’t forget!

When you want to load more content on a page, but don’t want the user to have to click a link — implementing something called “infinite scrolling” is a good option. It seems there is quite a debate — see comments in the article — on whether or not this is a good practice. Personally, I like it, but some people seem to find pagination more useful. I think it depends on the application.

Here’s how to implement it:

Add a div in your page where you’d like to add more content when the users scrolls.


Get the latest version of the jquery library or alternatively just use the jquery library hosted by Google and add this piece of code at the bottom of your page (right before the tag):

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

Then, add this code:

$(document).ready(function(){
	var height = $(document).height() - $(window).height() - 30;
	var scrollTriggered = false;
	$(window).scroll(function(){
		if($(window).scrollTop() >= height && !scrollTriggered )
		{	
			scrollTriggered = true;			
			$("#pageContent").append("
LOADING MORE CONTENT HERE
");
			scrollTriggered = false;

		}
	});
});

It’s a good practice to add javascript code at the bottom of your page. The developers at Yahoo have a list of good practices to speed up your website, one of them being adding javascript at the bottom.

Here’s a little rundown of how the code works:

  1. First calculate the height of the visible area of your page and subtract 30. Subtracting 30 makes it so the content is loaded before the user reaches the absolute bottom of the page.
    var height = $(document).height() - $(window).height() - 30;
  2. Add the scroll event handler (I’ll explain the scrollTriggered boolean in the next step). This code allows you to do something when your page is scrolled.
    $(window).scroll(function(){})
  3. Then, check if the position of the scroll bar is more than the calculated height (see step 1) and the scroll event hasn’t already been triggered.
    if($(window).scrollTop() >= height && !scrollTriggered )

    This is where the scrollTriggered boolean comes into play. When the scrollTriggered boolean is true, even if the scroll event is triggered multiple times, nothing will happen until the scrollTriggered boolean gets set back to false. This is important if you are making an AJAX request and need to retrieve a certain data set. If you don’t have this boolean, you could possibly retrieve the same data set multiple times.

  4. Set scrollTriggered = true and then either append some content (as in the above example) or make an AJAX request to retrieve more data.
    scrollTriggered = true;			
    $("#pageContent").append("

    LOADING MORE CONTENT HERE

    ");
    scrollTriggered = false;

    OR

    scrollTriggered = true;
    $.post('ajax/loadmore',function(data){scrollTriggered = false; $("#pageContent").append(data);})

    In the AJAX example above, notice I set the scrollTriggered back to false in the callback function. If you do make an AJAX request, make sure you set the scrollTriggered boolean back to false in the callback function, not after the entire AJAX request.

That’s about it! Not too complicated. And useful too!

Flexing my muscles

Last October, I was assigned a fairly large project at work. I started out developing the project using PHP/Javascript/CSS. It was moving along pretty smoothly and I was almost done (and when I say almost, I really mean it was pretty close to being done in Firefox, but I still had the ridiculous and monumental task of making it all work in Internet Explorer.) After a meeting with my boss and the people who were going to actually use the application, my boss decided it would be a good idea to port everything over to Flex.

As I dived into the task of porting everything, it became apparent that there were some benefits to using Flex, and some drawbacks. It also was somewhat depressing to see a lot of the work I had done go unused. Gotta do what the boss says though, right?

Flex Benefits

No, I’m not talking about health insurance, I’m talking about using Flex to write web applications. The first obvious benefit I found for me was that I didn’t have to deal with cross-browser issues when it came to CSS. Don’t get me wrong, I think CSS is great, I’m just not well-versed in all the different nuances each browser requires to make apps look all the same. I know enough to get by with simple web apps, but when it comes to complicated layouts, CSS can get tricky. It’s frustrating to get things “pixel perfect” in one browser, only to find out another browser (ahem, IE) looks completely ugly. With Flex,  I just write one app, and it looks the same in all browsers. That saves me a lot of frustration in one area of web development that isn’t my strong point.

Another thing I like about Flex is the concept of data binding. Basically, you can attach the keyword [Bindable] to any variable  or object and then any changes are  automatically propagated to all references of that variable or object inside the application. No need for an “onChange” or “onClick” function. It just happens automatically! The problem I was running into when I was using PHP/Javascript/CSS was that I would use Javascript to update information in one part of the application, but other parts of the application would still have stale data.

Check out this website for good examples of how data binding works.

Drawbacks

So, although Flex is great for some things, I found it annoying sometimes. One thing I don’t like is how bloated all the code seems.

For example:

In order to validate any text input, an extra line of code needs to be added for every individual text input. When you have a lot of inputs on one page, this can get really tedious.

The code for a form with a text input looks something like this:

‹mx:FormItem label="Name:" required="true"›

‹mx:TextInput id="nameInput"/›

 ‹/mx:FormItem›

Now, you’d think that little “required” property would check to make sure the text input has some sort of value in it. Nope, that attribute adds a red star (*) next to the input box so the user knows the input box is valid. That’s it! In order to make a text input required this is the code you need to add:

<Validator id="reqValid" required="true" source="{nameInput}" property="text"/>

The “source” property tells the Validator which input it needs to validate. In the example above, it will validate the Text Input that has the id  ‘nameInput’. The “property” attribute tells the validator what property to look for in the input. After writing this code about 15 times, I thought, “Doesn’t this violate the whole DRY principle?” There has to be a better solution than this.

The other thing I found annoying (as I’m sure a lot of users would agree) is that for no apparent reason, when the app is running in my browser, it will suddenly crash with no explanation of what went wrong. Not even a cryptic Windows-like error message will show up. Just a nice message from Firefox telling me my browser crashed (Duh!). Maybe this has something to do with the Flash player, but it gets really annoying to have to restart my browser and restore my tabs when that happens.

Although it was somewhat depressing to have redo a lot of my work, I’m glad I had the experience of writing the same web application in two different ways. It definitely gave me a better idea of what does and doesn’t work when it comes to web development and the tools you choose to create applications. I love my job!

Image