JQuery_ Novice to Ninja - Earle Castledine [89]
chapter_06/09_ajax_gallery_with_spinner/script.js (excerpt)
$('#spinner').fadeOut('slow', function() {
$(this).remove();
});
Tip: Simulating Server Latency
If you have your code running on a local server, your requests are often going to be answered very quickly—far quicker than the time it takes to see your fading animations in action. Most server-side languages have a method to “sleep” for a given amount of time before returning. For example, in PHP you can use sleep(4); to wait for four seconds before continuing. This can help make your testing a bit more realistic.
Global Progress Indicator
We could add individual spinners to every part of the page that will be affected by Ajax requests, but in the end our page is going to contain a whole bunch of Ajax interactions which are all centered around the same widget. We might as well add a global spinner that sits on top of our widget, and let this serve as an indicator for all Ajax events. Whenever any Ajax requests commence, the spinner will be displayed. When all requests have completed, it stops.
Let’s start by adding a place for our progress indicator to go. (Although you could add and remove it dynamically as we did earlier, our global element will be used so often that we’ll leave it on the page.) We’ll also add a class that we’ll attach and remove from the element at the appropriate times:
chapter_06/10_global_event_handlers/gallery.css (excerpt)
.progress {
background: #fff url(progress.gif) no-repeat center right;
}
Then we register the global Ajax event handlers ajaxStart and ajaxStop. Remember, the ajaxStart method is run when an Ajax request occurs and no other requests are currently running, and ajaxStop is fired after all requests have finished.
Note: How does jQuery know?
Internally, the number of Ajax requests in progress is tracked by a counter. You can access this counter at any time via the $.active property. This will return a numeric value containing the number of currently working Ajax requests.
Here are our global handlers:
chapter_06/10_global_event_handlers/script.js (excerpt)
$('#ajaxInProgress')
.ajaxStart(function() {
$(this).addClass('progress');
})
.ajaxStop(function() {
$(this).removeClass('progress');
});
Tip: Set up the Progress Indicator First
There is one gotcha to look out for when you’re loading content via Ajax when your page loads. You’ll need to define your global handlers before you do your initial requests, otherwise they’ll miss the events being fired.
Endless Scrolling
Ajax allows us to grab more content from the server whenever we want. At some stage, someone realized that this meant paginating data was no longer absolutely necessary; instead of scrolling to the bottom of the page and hitting a Next link, we could just load in more content automatically.
This kind of endless scrolling is a technique that’s gaining popularity as a way of displaying large amounts of data: images, comments, RSS feeds, emails … but it has its detractors.
Endless scrolling can easily be misused; you need to gauge your needs and decide if it’s appropriate. You must ensure that the interaction makes sense to the user and feels natural to use. For StarTrackr!, an endless scroll works, as the images are more like a random stream of pictures, and the users are unconcerned with the scale of the data; there’s no need for them to know they’re on picture 10 of 1037, for example.
Before we get underway on the second phase of our Ajax gallery, we will need to remove the setTimeout call from the complete event handler. We want the user to be in control now, instead of the timer.
The first requirement for an endless scrolling component is, unsurprisingly, a scroll bar. We’ll display one by setting overflow:auto on our gallery container and reducing its width a little.
We’ve added a couple of new methods to our GALLERY object: an init() function for performing some necessary setup code, and a checkScroll() method which will be called whenever the scroll event fires:
chapter_06/11_endless_scrolling/script.js