Cómo añadir una barra de progreso en tu página web

Desde el boom de la telefonía móvil, las páginas webs se están convirtiendo en apps más que en otra cosa. Conceptos que tienen más sentido en una aplicación de ámbito local son transferidos al ámbito web. Uno de estos conceptos es la reciente incorporación de barras de progreso para mostrar el estado de carga de una página, tal y como hacen muchas webs de Google como Gmail.

En este tutorial vamos a utilizar el nuevo plugin NProgress para agregar una barra de progreso en tu página web. Si deseas obtener más información, por favor, sigue leyendo.

El plugin NProgress

NProgress es un plugin de jQuery que muestra una barra de progreso interactiva en la parte superior de la página, inspirado por el que se usa en páginas como YouTube. Esto consta de un objeto global, NProgress, que contiene un número de métodos a los cuales puedes llamar para mostar la barra de progreso.

La página de github del plugin sugiere que puedes agregar la función NProgress.start() a tu $(document).ready(), y la función NProgress.done() al $(window).load() para que sea más sencilla la integración del plugin. Esto no mostrará el progreso real (para eso tendrás que supervisar todos los recursos que se incluyen en la página e incrementar la barra manualmente), sin embargo la mayoría de los visitantes ni se darán cuenta.

Ahora que tienes una ligera idea de cómo se utiliza NProgress (recomendamos leer la doc del plugin), vamos a desarrollar un ejemplo un poco más complicado: una galería que muestra una barra de progreso durante la carga de imágenes. La barra se corresponderá con el número real de las imágenes cargadas.

La galería

Como siempre, empezamos con el código HTML. En esta ocasión es muy simple, sólo necesitamos un div que ampare las fotos y un botón de carga.

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>

He incluido una custom font de Google WebFonts y dos hojas de estilo en el head. También he añadido llamadas a tres ficheros Javascript antes del cierre del body.

Ahora empezamos con lo interesante, la parte de jQuery del tutorial. Utilizo el objeto Deferred para mostrar las fotos de forma consecutiva. Esto es necesario porque queremos que las fotos se descarguen en paralelo (lo cual es mucho más rápido), pero desaparezcan a la vista una tras otra. Este artículo es demasiado corto para explicar cómo funcionan las referencias, en otro artículo hablaremos largo y tendido de ellas. Por resumir, son una herramienta poderosa con las que se pueden simplificar las interacciones asíncronas.

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 = $('
 
').appendTo(elem);

		// Load the image in memory

		var 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);

La barra de progreso se incrementará con cada imagen cargada debido a la callback function que detecta el evento de imagen cargada. De esta manera la función ShowImage es libre de manejar solamente la carga y visualización de las fotos.

¡Con esto la barra de progreso para una galería estaría lista!

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP