Быстрые подсказки: добавляем на свой сайт панель прогресса загрузки

Скачать исходный код

Демонстрация

С развитием технологий мобильных устройств, веб-сайты все больше и больше превращаются в площадки для запуска приложений.

Общая тенденция такова, что больше уже не имеет смысла устанавливать программу на локальном устройстве, но проще запускать ее онлайн. В рамках этих новаций на некоторых сайтах Google сейчас устанавливаются панели прогресса загрузки, на которых отображается состояние загрузки страницы.

Для установки этой мгновенной подсказки мы будем использовать новый плагин JQuery NProgress. С его помощью индикатор добавляется на веб-страницу. Если хотите узнать об этом больше, читайте статью!

Плагин NProgress

NProgress является JQuery плагином, который выводит в верхней части страницы интерактивный индикатор, похожий на те, что загружаются на YouTube. Его основой является объект NProgress. Он задает несколько разных методов, которыми можно отображать состояние выполнения загрузки. Вот код, представляющий демонстрацию данных вариантов:

JS:

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

});

HTML:

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

CSS:

*{
	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;
}

На домашней странице плагина описывается, как подключить функцию NProgress.start()при обработке запроса $(document).ready() и функцию NProgress.done() при выводе $(window).load(). Таким довольно несложным способом осуществляется интеграция плагина.

Это не будет отвечать абсолютно точно прогрессу загрузки (для этого потребуется отслеживать загрузку элементов вашей страницы, которые задействуют другие ресурсы – нужно расширить функции плагина вручную), однако погрешность будет незначительная, и большинство людей этого даже не заметят.

Теперь у вас есть общее понятие о том, как используется NProgress. Давайте рассмотрим более сложный пример — галерея, в которой прогресс-бар выводится при загрузке изображений. Информация на этой панели будет соответствовать фактическому количеству загружаемых изображений.

Галерея

Как обычно, мы начинаем с HTML-разметки. На этот раз все очень просто – нам понадобится только несколько блоков DIV, чтобы вывести фотографии и кнопку загрузки:

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" />

        <!—Таблица стилей -->
        <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>

В том числе я использовал несколько специальных шрифтов из Google WebFonts, а также два стиля прописанных в <head>, и три файла JavaScript вызываемых перед тегом </body>.

Галерея

Панель прогресса загрузки

Рассмотрение этого JQuery-кода – более интересная часть урока. Здесь я использую специальный объект для разграничения, чтобы выводить фотографии последовательно.

Это необходимо, для того, чтобы мы в процессе параллельного скачивания фотографий (это значительно ускоряет процесс) видели, как они загружаются одна за другой. Эта статья слишком коротка, чтобы объяснить от и до, как работает Deferred – для этого вы можете ознакомиться с материалами по одной из этих ссылок: ссылка 1, ссылка 2, ссылка 3. В общем это очень мощный инструмент, позволяющий упростить асинхронные взаимодействия.

assets/js/script.js

(function($){

    // Массив фотографий, которые будут выводиться на странице. Вместо жесткой 
    // привязки вы можете загружать их с сервера через 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(){		

        // Задаем некоторые переменные

        var page = 0,
            loaded = 0,
            perpage = 10,
            main = $('#main'),
            expected = perpage,
            loadMore = $('#loadMore');

        // Запускаем режим отслеживания действий пользователей по загрузке
        // изображений
        main.on('image-loaded', function(){

            // Когда такое действие зафиксировано, загружается индикатор загрузки
            loaded++;

            // NProgress.set принимает одно из возможных значений – 0 или 1
            NProgress.set(loaded/expected);

            if(page*perpage >= photos.length){

                // Когда все фото загружены,
                // кнопка «Загрузить» убирается со страницы

                loadMore.remove();
            }
        });

        // Когда нажимается кнопка «Загрузить», выводится еще 10 изображений
        // (задается через значение переменной perpage)

        loadMore.click(function(e){

            e.preventDefault();

            loaded = 0;
            expected = 0;

            // Здесь первое изображение передается в обработку объекту разграничения
            // так, чтобы оно выводилось немедленно.
            var deferred = $.Deferred().resolve();

            // Загружаем часть массива и выводим фотографии. В зависимости от
            // размеров массива число выводимых фотографий может оказаться и
            // меньше, чем задано perpage. Если общее количество фото в массиве
            // меньше числа perpage.
            $.each(photos.slice(page*perpage, page*perpage + perpage), function(){

                // Передаем объекту разграничения по одному изображению, выводимому
                // через showImage. Таким образом обеспечивается поступательное
                 // отображение их загрузки – одно за другим. 
                deferred = main.showImage(this, deferred);

                expected++;
            });

            // Запуск анимации панели прогресса загрузки
           NProgress.start();

            page++;
        });

        loadMore.click();
    });

    // Создаем новый jQuery плагин, который выводит на экран изображение из
    // активного элемента, после того как он загружен. Плагин оперирует двумя
    // аргументами:
    //	* src - URL изображения
    //	* deferred - объект разграничения jQuery, созданный во время предыдущего
    // обращения к функции showImage
    // 
    // Возвращаемся к объекту разграничения, который закрывается, когда
    // изображение загружено.
    $.fn.showImage = function(src, deferred){

        var elem = $(this);

        // Эта функция снова запускает объект разграничения

        var result = $.Deferred();

        // Создание блока div для фото, в котором будут находиться параметры
        // вывода изображения
        var holder = $('<div class="photo" />').appendTo(elem);

        // Загрузка изображения в память

        var img = $('<img>');

        img.load(function(){

            // Фото загружено! Используем метод .always() для разграничения, чтобы 
            // отображать загрузку следующего изображения, когда предыдущее уже
            // загружено. Когда это происходит, выводится панель состояние 
            // загрузки текущего фото.

            deferred.always(function(){

                // Trigger a custom event on the #main div:
                elem.trigger('image-loaded');

                // Изображение размещается на странице с заданными для него
                // эффектами анимации.

                img.hide().appendTo(holder).delay(100).fadeIn('fast', function(){

                    // Завершает работу объекта разграничения. После чего отправляется 
                    // уведомление, что следуееще фото может выводиться на странице и
                    // обрабатываться функцией .always()
                    result.resolve()
                });
            });

        });

        img.attr('src', src);

        // Вновь запуск объекта разграничения (на текущий момент он был закрыт)
        return result;
    } 

})(jQuery);

Индикатор прогресса загрузки запускается при каждой загрузке с помощью функции, которая отслеживает каждое такое действие пользователей. Таким образом функция showImage обрабатывает только процесс загрузки и вывода изображения.

Теперь это завершенный скрипт для отображения панели состояния загрузки изображений в галерею!

РедакцияПеревод статьи «Quick Tip: Add a Progress Bar to Your Site»