AJAX Прелоадеры
Многие программисты оптимизируют JavaScript и CSS-код, чтобы страница грузилась быстрее. Но не все из них делают прелоадеры, которые дают пользователю эффект субъективно более быстрой загрузки.
Способ №1. Дешево и сердито.
Идея проста — необходимо поместить по центру картинку, которая будет показывать пользователю, что страница все еще загружается. Код довольно прост, пишем сразу после <body>:
<div id="preloaderbg" class="centerbg1">
<div class="centerbg2">
<div id="preloader"></div>
</div>
</div>
<script type="text/javascript">
document.getElementById('preloaderbg').style.display
= 'block';
document.body.style.overflow = 'hidden';
</script>
CSS-код:
.centerbg1 {
display: none;
width:100%;
height:100%;
position: absolute;
top: 0px;
left: 0px;
z-index: 1000;
background:
url('/design/im/texture1.jpg') #3c363e;
}
.centerbg2 {
position: absolute;
left: 50%;
top: 50%;
}
#preloader {
top: -50%;
left: -50%;
position: relative;
width: 333px;
height: 26px;
background:
url('/content/pages/articles/preloaders/bg2.gif');
border: solid #edda3d 2px;
}
В результате у нас сразу после загрузки появляется блок с анимированным прогрессбаром по центру страницы. Параметр overflow нужно менять для того, чтобы не появилась полоса прокрутки и пользователь не мог прокрутить вниз и поглядеть на содержимое странички.
Потом, когда все загрузилось — нужно убрать прелоадер и установить overflow в положение visible.
document.getElementById('loaderbg').style.display = 'none';
document.body.style.overflow = 'visible';
Эту часть кода я поместил в файл с JS-функциями, plreloader1.js
Если делать прогрессбар из анимированного GIF-рисунка, то он может получиться слишком тяжелым, порой даже больше самой странички, где его размещают. Поэтому лучше нарисовать полоску (например,такую), поставить ее как фон у блока с ID preloader и двигать бекграунд-позишн по таймеру.
<script type="text/javascript">
document.getElementById('loaderbg').style.display
= 'block';
document.body.style.overflow = 'hidden';
pbPos = 0;
pbInt = setInterval(function() {
document.getElementById('preloader').
style.backgroundPosition = ++pbPos + 'px 0';
}, 25);
</script>
И после загрузки делаем вот что:
clearInterval(pbPos);
document.getElementById('loaderbg').style.display = 'none';
Результат работы можно посмотреть тут.
У этого способа есть недостатки. Если ставить скрытие прелоадера на onload, т.е. когда ждать, пока загрузятся все картинки, то пользователь может подумать, что страница просто зависла — фактически кроме анимации ничего не происходит. Если же вешать на $(document).ready() из jQuery, то после исчезновения прелоадера картинки только будут подгружаться.
Поэтому предлагается использовать…
Способ №2. Истина где-то рядом, или джедаи наносят ответный удар.Для начала нарисуем 2 полосы загрузки — активную и не очень.
Поставим неактивную как фон, а активную сделаем фоном у дива, для которого будем менять ширину в зависимости от процента загрузки.
<div id="loaderbg" class="centerbg1">
<div class="centerbg2">
<div id="preloader">
<img alt="Загрузка..."
src="/design/im/progbar_ph.gif" />
<div id="progbarfg"></div>
</div>
</div>
</div>
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> следущее, мы получим прогрессбар, который будет показывать ход загрузки всего контента на странице, после чего плавно исчезнет.
<script type="text/javascript">
dLoader.start('mainprogbarfg', 333, 'size',
function(){ $('#preloaderbg').fadeOut(250); });
</script>
Когда загрузились все JS-файлы, запускаются функции, которые есть в массиве invoke. Если мы с помощью jQuery подгружаем контент, то функция будет выглядить так:
function fn(callBack){
$.get('/', params, function(data){
someHandler(data); eval(callBack);
});
}
PHP-скрипт делает следующее: он заносит в массив необходимые скрипты с их размерами, а так же картинки и дополнительные функции. Код:
$data['js'] = array(
array('path' => 'jquery-1.2.6.min.js',
'size' => filesize($jsRoot.'/jquery-1.2.6.min.js')),
array('path' => 'functions.js',
'size' => filesize($jsRoot.'/functions.js'))
);
$data['im'] = GetFiles($imgRoot, true);
$data['invoke'][] = array(
'action' => 'loadTemplates',
'size' =>
GetDirSize(dirname(__FILE__).'/design/
ajax templates/', false)
);
$data['jspath'] = '/design/js/';
$data['impath'] = '/design/im';
Уже после того, как загрузились все картинки и JS-файлы, вызывается событие onLoad, которое вы указали в функции dLoader.start()
Еще есть способ кастомизации процесса загрузки:
dLoader.userProgress =
function(bytesLoaded, totalBytes){ doSmth(); }
Для того, чтобы использовать это, нужно отредактировать PHP-скрипт, прописав в нем свои пути и JS-библиотеки, затем запустить его, чтобы он сгенерировал скрипт загрузчика. Ну и прописать его между <head> и </head>.
Работающий пример второго варианта лежит здесь.
Архив со скриптами можно взять отсюда







