Sugerencia rápida:agregue una barra de progreso a su sitio

Desde la llegada de los dispositivos móviles, los sitios web se están convirtiendo cada vez más en "aplicaciones". Los conceptos que tienen sentido para una aplicación que se ejecuta localmente se transfieren a la web. Uno de ellos es la reciente adición de "barras de progreso" a algunos de los sitios web de Google que muestran el estado de carga de la página.

En este consejo rápido, usaremos el nuevo complemento NProgress jQuery para agregar una barra de progreso a una página web. Si desea obtener más información, ¡siga leyendo!

El complemento NProgress

NProgress es un complemento de jQuery que muestra una barra de progreso interactiva en la parte superior de su página, inspirada en la de YouTube. Consiste en un objeto global - NProgress que contiene una serie de métodos a los que puede llamar para avanzar en la barra de progreso. Aquí hay una demostración rápida de los métodos:

$(function(){

    // Quick Load

    $('button.quick-load').click(function(){
        NProgress.done(true);
    });

    // Incremental Load

    $('button.show-progress-bar').click(function(){
        NProgress.start();
    });

    $('button.load-one-item').click(function(){
        NProgress.inc();
    });

    $('button.finish').click(function(){
        NProgress.done();
    });

    // Percentage Load

    $('button.set-to-25').click(function(){
        NProgress.set(0.25);
    });

    $('button.set-to-75').click(function(){
        NProgress.set(0.75);
    });

});
<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>
*{
    margin:0;
    padding:0;
}

body{
    font:14px/1.3 'PT Sans', sans-serif;
    color: #5e5b64;
    padding:40px 40px 0;
}

h1{
    font-size:18px;
    padding-bottom:4px;
}

button{

    background-color: #78bad6;
    box-shadow: 0 0 5px #8fcde7 inset, 0 1px 1px #eee;

    display: inline-block;
    padding: 9px 15px;
    margin: 20px auto 20px;

    font-weight: bold;
    font-size: 12px;
    text-align: center;
    color: #fff;

    border-radius: 2px;
    box-shadow: 0 1px 1px #e0e0e0;
    border: 0;

    opacity:1;
    cursor: pointer;
}

button:hover{
    opacity: 0.9;
}

La página del complemento github sugiere que conecte el NProgress.start() función a su $(document).ready() devolución de llamada y NProgress.done() a $(window).load() que es una manera muy fácil de integrar el complemento. Esto no mostrará el progreso real (para eso tendrás que monitorear todos los recursos que están incluidos en tu página e incrementar la barra manualmente), sin embargo, la mayoría de la gente no lo notará de todos modos.

Ahora que tiene una buena idea de cómo se usa NProgress, hagamos un ejemplo más complicado:una galería que muestra una barra de progreso mientras carga imágenes. La barra corresponderá al número real de imágenes cargadas.

La Galería

Como de costumbre, comenzamos con el marcado HTML. Esta vez es muy simple, solo necesitamos un div para guardar 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="https://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>

Estoy incluyendo una fuente personalizada de Google Webfonts y dos hojas de estilo en el <head> y tres archivos JavaScript antes del cierre </body> etiqueta.

Las cosas se ponen más interesantes en la parte de jQuery del tutorial. Aquí estoy usando el objeto Diferido para mostrar las fotos consecutivamente. Esto es necesario porque queremos que las fotos se descarguen en paralelo (que es mucho más rápido), pero que se desvanezcan una tras otra. Este artículo es demasiado corto para explicar cómo funcionan los diferidos, pero puede leer uno de estos:enlace, enlace, enlace. Son una herramienta poderosa que puede simplificar las interacciones asincrónicas.

activos/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);

La barra de progreso se incrementa con cada imagen cargada por la función de devolución de llamada que escucha la imagen cargada evento personalizado. De esta manera el showImage La función es gratuita para manejar solo la carga y visualización de las fotos.

¡Con esto la barra de progreso de la galería está lista!