Pull to refresh

Делаем полноценный JS-прелоадер для AJAX-приложения

Website development
Многие программисты оптимизируют JavaScript и CSS-код, чтобы страница грузилась быстрее.
Но не все они делают прелоадеры, которые дают пользователю эффект субъективно более быстрой загрузки.

Способ №1. Дешево и сердито.
Идея проста — необходимо поместить по центру картинку, которая будет показывать пользователю, что страница все еще загружается. Код довольно прост, пишем сразу после <body>:

  1. <div id="preloaderbg" class="centerbg1">
  2. <div class="centerbg2">
  3. <div id="preloader"></div>
  4. </div>
  5. </div>
  6. <script type="text/javascript">
  7. document.getElementById('preloaderbg').style.display = 'block';
  8. document.body.style.overflow = 'hidden';
  9. </script>
* This source code was highlighted with Source Code Highlighter.


CSS-код:

  1. .centerbg1 {
  2. display: none;
  3. width:100%;
  4. height:100%;
  5. position: absolute;
  6. top: 0px;
  7. left: 0px;
  8. z-index: 1000;
  9. background: url('/design/im/texture1.jpg') #3c363e;
  10. }
  11. .centerbg2 {
  12. position: absolute;
  13. left: 50%;
  14. top: 50%;
  15. }
  16. #preloader {
  17. top: -50%;
  18. left: -50%;
  19. position: relative;
  20. width: 333px;
  21. height: 26px;
  22. background: url('/content/pages/articles/preloaders/bg2.gif');
  23. border: solid #edda3d 2px;
  24. }
* This source code was highlighted with Source Code Highlighter.


В результате у нас сразу после загрузки появляется блок с анимированным прогрессбаром по центру страницы. Параметр overflow нужно менять для того, чтобы не появилась полоса прокрутки и пользователь не мог прокрутить вниз и поглядеть на содержимое странички.

Потом, когда все загрузилось — нужно убрать прелоадер и установить overflow в положение visible.

  1. document.getElementById('loaderbg').style.display = 'none';
  2. document.body.style.overflow = 'visible';
* This source code was highlighted with Source Code Highlighter.


Эту часть кода я поместил в файл с JS-функциями, plreloader1.js

Если делать прогрессбар из анимированного GIF-рисунка, то он может получиться слишком тяжелым, порой даже больше самой странички, где его размещают.
Поэтому лучше нарисовать полоску (например, такую), поставить ее как фон у блока с ID preloader и двигать бекграунд-позишн по таймеру.

  1. <script type="text/javascript">
  2. document.getElementById('loaderbg').style.display = 'block';
  3. document.body.style.overflow = 'hidden';
  4. pbPos = 0;
  5. pbInt = setInterval(function() {
  6. document.getElementById('preloader').style.backgroundPosition = ++pbPos + 'px 0';
  7. }, 25);
  8. </script>
* This source code was highlighted with Source Code Highlighter.


И после загрузки делаем вот что:
  1. clearInterval(pbPos);
  2. document.getElementById('loaderbg').style.display = 'none';
* This source code was highlighted with Source Code Highlighter.


Результат работы можно посмотреть тут.

У этого способа есть недостатки — Если ставить скрытие прелоадера на onload, т.е. когда ждать, пока загрузятся все картинки, то пользователь может подумать, что страница просто зависла — фактически кроме анимации ничего не происходит. Если же вешать на $(document).ready() из jQuery, то после исчезновения прелоадера картинки только будут подгружаться.

Поэтому предлагается использовать…

Способ №2. Истина где-то рядом, или джедаи наносят ответный удар.
Для начала нарисуем 2 полосы загрузки — активную и не очень.

Неактивная полоса
Активная полоса

Поставим неактивную как фон, а активную сделаем фоном у дива, для которого будем менять ширину в зависимости от процента загрузки.

  1. <div id="loaderbg" class="centerbg1">
  2. <div class="centerbg2">
  3. <div id="preloader">
  4. <img alt="Загрузка..." src="/design/im/progbar_ph.gif" />
  5. <div id="progbarfg"></div>
  6. </div>
  7. </div>
  8. </div>
* This source code was highlighted with Source Code Highlighter.


progbar_ph.gif – это картинка высотой в 1 пиксель и шириной с нашу полосу прокрутки (данный пример глючит без нее в IE, и я пока не нашел другого способа выровнять по центру див с прогрессбаром).
Стили такие же, как и в предыдущем способе, разве что
#progbarfg {width: 0px; background: url(‘/design/im/progbar_fg.png’)}


Теперь осталось сделать небольшой скрипт, который будет динамически подгружать содержимое сайта и картинки. Он нужен для того, чтобы прогрессбар показывался и изменялся еще до того, как скачается используемый фреймворк и другие JS-файлы.

Возьмем средний сайт, сделанный полностью на AJAX. Загрузка примерно происходит так:
  • грузится HTML-код
  • начинают грузиться картинки
  • затем некий фреймворк
  • дополнительные JS-файлы (хотя лучше все склеить в один)
  • запускается некая функция (или несколько), которая стягивает дополнительный контент.

Всему этому (за вычетом CSS и HTML) мы назначаем вес в байтах (или условный вес), например, единицу, и по мере загрузки каждого файла (или выполнения функции) мы двигаем наш прогрессбар.

Я реализовал 2 метода — первый простой, включается так:
непосредственно перед </body> пишем:

<script type="text/javascript">
dLoader.start('progbarfg', 333, 'count');
</script>


Первым параметром идет идентификатор блока с активной полосой загрузки в качестве фона, вторым — ширина картинки, третий параметр — это метод, которым будем считать вес контента.

Скрипт сканирует все картинки на страницы и назначает им вес равный 1. Все JS-файлы прописываются в его теле, как я расскажу чуть ниже.
Однако хочется, чтобы вес у каждой единицы контента был не единицей, а реальным объемом в байтах. Да и для AJAX-приложений хотелось бы сразу подгрузить всю графику.

Для этого я написал скрипт на PHP, который сканирует папку с картинками оформления и заносит это все дело с размерами файлов в массив, опционально сжимая.

Так что дописав перед </body> следущее, мы получим прогрессбар, который будет показывать ход загрузки всего контента на странице, после чего плавно исчезнет.

  1. <script type="text/javascript">
  2. dLoader.start('mainprogbarfg', 333, 'size', function(){ $('#preloaderbg').fadeOut(250); });
  3. </script>
* This source code was highlighted with Source Code Highlighter.


Когда загрузились все JS-файлы, запускаются функции, которые есть в массиве invoke. Если мы с помощью jQuery подгружаем контент, то функция будет выглядить так:

  1. function fn(callBack){
  2. $.get('/', params, function(data){ someHandler(data); eval(callBack); });
  3. }
* This source code was highlighted with Source Code Highlighter.


PHP-скрипт делает следующее: он заносит в массив необходимые скрипты с их размерами, а так же картинки и дополнительные функции. Код:

  1. $data['js'] = array(
  2. array('path' => 'jquery-1.2.6.min.js', 'size' => filesize($jsRoot.'/jquery-1.2.6.min.js')),
  3. array('path' => 'functions.js', 'size' => filesize($jsRoot.'/functions.js'))
  4. );
  5. $data['im'] = GetFiles($imgRoot, true);
  6. $data['invoke'][] = array(
  7. 'action' => 'loadTemplates',
  8. 'size' => GetDirSize(dirname(__FILE__).'/design/ajax templates/', false)
  9. );
  10. $data['jspath'] = '/design/js/';
  11. $data['impath'] = '/design/im';
* This source code was highlighted with Source Code Highlighter.


Уже после того, как загрузились все картинки и JS-файлы, вызывается событие onLoad, которое вы указали в функции dLoader.start()

Еще есть способ кастомизации процесса загрузки:

  1. dLoader.userProgress = function(bytesLoaded, totalBytes){ doSmth(); }
* This source code was highlighted with Source Code Highlighter.


Для того, чтобы использовать это, нужно отредактировать PHP-скрипт, прописав в нем свои пути и JS-библиотеки, затем запустить его, чтобы он сгенерировал скрипт загрузчика, который потом нужно прописать в <head> единственным скриптом.
Работающий пример второго варианта лежит здесь.

Архив со скриптами можно взять отсюда, ну а посмотреть, как это все работает — на моем сайте.

Работает в Internet Explorer 6/7, Firefox 3, Opera 9.5, Safari 3.2.1

Пожелания и предложения приветствуются :)

Спасибо за помощь в подготовке статьи waitekk отсыпьте ему кармы а мне еще травы
Tags:JavaScriptCSSВеб 2.0ajaxpreloader
Hubs: Website development
Total votes 63: ↑53 and ↓10 +43
Views35K

Popular right now

Node.js: серверный JavaScript
June 28, 202127,000 ₽Loftschool
Веб-дизайнер
June 28, 202183,000 ₽GeekBrains
Веб-разработчик
June 28, 202162,000 ₽Loftschool

Top of the last 24 hours