Rychlý tip:Přidejte na svůj web ukazatel průběhu

Od nástupu mobilních zařízení se webové stránky stále více mění v „aplikace“. Koncepty, které mají smysl pro lokálně běžící aplikaci, se přenášejí na web. Jedním z nich je nedávné přidání „ukazatelů průběhu“ na některé weby Google, které ukazují stav načítání stránky.

V tomto rychlém tipu použijeme nový plugin NProgress jQuery k přidání ukazatele průběhu na webovou stránku. Pokud se chcete dozvědět více, pokračujte ve čtení!

Plugin NProgress

NProgress je plugin jQuery, který zobrazuje interaktivní lištu průběhu v horní části stránky, inspirovanou tím na YouTube. Skládá se z globálního objektu - NProgress který obsahuje řadu metod, které můžete volat k posunutí ukazatele průběhu. Zde je rychlá ukázka metod:

$(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;
}

Stránka pluginu github navrhuje, abyste připojili NProgress.start() funkce na váš $(document).ready() zpětné volání a NProgress.done()$(window).load() což je velmi snadný způsob integrace pluginu. To neukáže skutečný pokrok (k tomu budete muset sledovat všechny zdroje, které jsou zahrnuty na vaší stránce, a manuálně zvyšovat lištu), nicméně většina lidí si toho stejně nevšimne.

Nyní, když máte dobrou představu o tom, jak se NProgress používá, udělejme si složitější příklad – galerii, která ukazuje ukazatel průběhu při načítání obrázků. Lišta bude odpovídat skutečnému počtu načtených obrázků.

Galerie

Jako obvykle začínáme se značkami HTML. Tentokrát je to velmi jednoduché, potřebujeme pouze div pro uložení fotek a tlačítko načíst:

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>

Do <head> vkládám vlastní písmo z Google Webfonts a dvě šablony stylů a tři soubory JavaScript před závěrečnou </body> tag.

Věci jsou zajímavější v části jQuery výukového programu. Zde používám objekt Deferred k zobrazení fotografií po sobě. To je potřeba, protože chceme, aby se fotky stahovaly paralelně (což je mnohem rychlejší), ale aby se postupně stahovaly. Tento článek je příliš krátký na to, aby vysvětlil, jak Deferreds fungují, ale můžete si přečíst jeden z těchto:odkaz, odkaz, odkaz. Jsou mocným nástrojem, který může zjednodušit asynchronní interakce.

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

Ukazatel průběhu se zvyšuje s každým načteným obrázkem pomocí funkce zpětného volání, která naslouchá načtenému obrázku vlastní událost. Tímto způsobem showImage Tato funkce je volná pouze pro načítání a zobrazování fotografií.

Tím je ukazatel průběhu galerie připraven!