In this quick tip, we will use the new NProgress jQuery plugin to add a progress bar to a web page. If you’d like to learn more, keep reading!
The NProgress Plugin
NProgress is a jQuery plugin that shows an interactive progress bar on the top of your page, inspired by the one on YouTube. It consists of a global object –NProgress
which holds a number of methods that you can call to advance the progress bar. Here is a quick demo of the methods:<div>
<h1>Quick Load</h1>
<p>Show the progress bar quickly. This is useful for one-off tasks like AJAX requests and page loads.</p>
<button class="quick-load">Quick Load</button>
</div>
<div>
<h1>Incremental Load</h1>
<p>The progress bar is incremented with every element that is loaded. This can be useful in web apps that load multiple items.</p>
<button class="show-progress-bar">Show Progress Bar</button>
<button class="load-one-item">Load An Item</button>
<button class="finish">Finish Loading</button>
</div>
<div>
<h1>Percentage Load</h1>
<p>NProgress lets you set the progress bar to a specific percentage. This can be useful in apps where you know the total number of the items to be loaded, so you can calculate the percentage. This is the technique that we will use in the demo.</p>
<button class="show-progress-bar">Show Progress Bar</button>
<button class="set-to-25">Set to 25% Loaded</button>
<button class="set-to-75">Set to 75% Loaded</button>
<button class="finish">Finish Loading</button>
</div>
The plugin github page suggests that you hook up the
NProgress.start()
function to your $(document).ready()
callback and NProgress.done()
to $(window).load()
which is a very easy way to integrate the plugin. This won’t show the
real progress (for that you will have to monitor all the resources that
are included in your page and increment the bar manually), however most
people won’t notice anyway.Now that you have a good idea of how NProgress is used, let’s make a more complicated example – a gallery that shows a progress bar while loading images. The bar will correspond to the actual number of images loaded.
The Gallery
As usual, we start off with the HTML markup. This time it is very simple, we only have need a div to hold the photos, and a load button:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Quick Tip: Add a Progress Bar to Your Site</title>
<link href="http://fonts.googleapis.com/css?family=PT+Sans+Narrow:700" rel="stylesheet" />
<!-- The Stylesheets -->
<link href="assets/nprogress/nprogress.css" rel="stylesheet" />
<link href="assets/css/style.css" rel="stylesheet" />
</head>
<body>
<h1>Gallery Progress Bar</h1>
<div id="main"></div>
<a href="#" id="loadMore">Load More</a>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="assets/nprogress/nprogress.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
I am including a custom font from Google Webfonts and two stylesheets in the <head>
, and three JavaScript files before the closing </body>
tag.Things get more interesting in the jQuery part of the tutorial. Here I am using the Deferred object to show the photos consecutively. This is needed, because we want the photos to download in parallel (which is much faster), but fade into view one after the other. This article is too short to explain how Deferreds work, but you can read through one of these: link, link, link. They are a powerful tool that can simplify asynchronous interactions.
assets/js/script.js
(function($){
// An array with photos to show on the page. Instead of hard
// coding it, you can fetch this array from your server with AJAX.
var photos = [
'assets/photos/1.jpg', 'assets/photos/2.jpg',
'assets/photos/3.jpg', 'assets/photos/4.jpg',
// more photos here
];
$(document).ready(function(){
// Define some variables
var page = 0,
loaded = 0,
perpage = 10,
main = $('#main'),
expected = perpage,
loadMore = $('#loadMore');
// Listen for the image-loaded custom event
main.on('image-loaded', function(){
// When such an event occurs, advance the progress bar
loaded++;
// NProgress.set takes a number between 0 and 1
NProgress.set(loaded/expected);
if(page*perpage >= photos.length){
// If there are no more photos to show,
// remove the load button from the page
loadMore.remove();
}
});
// When the load button is clicked, show 10 more images
// (controlled by the perpage variable)
loadMore.click(function(e){
e.preventDefault();
loaded = 0;
expected = 0;
// We will pass a resolved deferred to the first image,
// so that it is shown immediately.
var deferred = $.Deferred().resolve();
// Get a slice of the photos array, and show the photos. Depending
// on the size of the array, there may be less than perpage photos shown
$.each(photos.slice(page*perpage, page*perpage + perpage), function(){
// Pass the deferred returned by each invocation of showImage to
// the next. This will make the images load one after the other:
deferred = main.showImage(this, deferred);
expected++;
});
// Start the progress bar animation
NProgress.start();
page++;
});
loadMore.click();
});
// Create a new jQuery plugin, which displays the image in the current element after
// it has been loaded. The plugin takes two arguments:
// * src - the URL of an image
// * deferred - a jQuery deferred object, created by the previous call to showImage
//
// Returns a new deferred object that is resolved when the image is loaded.
$.fn.showImage = function(src, deferred){
var elem = $(this);
// The deferred that this function will return
var result = $.Deferred();
// Create the photo div, which will host the image
var holder = $('<div class="photo" />').appendTo(elem);
// Load the image in memory
var img = $('<img>');
img.load(function(){
// The photo has been loaded! Use the .always() method of the deferred
// to get notified when the previous image has been loaded. When this happens,
// show the current one.
deferred.always(function(){
// Trigger a custom event on the #main div:
elem.trigger('image-loaded');
// Append the image to the page and reveal it with an animation
img.hide().appendTo(holder).delay(100).fadeIn('fast', function(){
// Resolve the returned deferred. This will notifiy
// the next photo on the page and call its .always() callback
result.resolve()
});
});
});
img.attr('src', src);
// Return the deferred (it has not been resolved at this point)
return result;
}
})(jQuery);
The progress bar is incremented with every loaded image by the callback function that listens for the image-loaded custom event. This way the showImage function is free to handle only the loading and displaying of the photos.by Martin Angelov
source: http://tutorialzine.com/2013/09/quick-tip-progress-bar/
0 komentar:
Post a Comment