Простая пост загрузка изображений с jQuery

На страницах современных сайтов, очень часто требуется организовать фотогалерею, слайд шоу, «карусельку» и jQuery для этих целей незаменима.
image
В одном проекте требовалось создать «слайдер» изображений с разрешением 980x613 пикселей, с автостартом слайдера после загрузки страницы и без особых ограничений на количество изображений. Средний вес изображения — 150кб.

Конечно же возникло несколько вариантов развития событий:
  • Динамическая (ajax) загрузка каждого последующего изображения слайдера
  • Загрузка страницы c несколькими первыми изображениями + пост загрузка статики.
Выбираем оптимальное для себя решение.
Динамическая загрузка каждого нового изображения
Здесь все предельно понятно, можно подгружать сами изображения с помощью ajax методом post и формировать html, например:

$.ajax({
    type: "POST",
    url: <image path>,
    enctype: 'multipart/form-data',
    complete: function(){
        // действие после выполнения ajax запроса
    }
})

Можно с помошью ajax сразу получать html.
В обоих случаях событие complete происходит после успешно выполненного ajax запроса, а при этом изображения еще могут быть не загружены. Убедиться в загрузке изображений поможет следующий код:

var img = new Image();
var loader = {
    load: function(imgPath) {
        img.src = imgPath;
    },
    // проверка загрузки изображения
    check: function() {
        if (img.complete) {
            loader.isload();
        } else {
            img.onload = loader.isload();
        }
    },
    isload: function(){
        // изображение загружено      
    }
}

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

Загрузка страницы с несколькими первыми изображениями и пост загрузка статики (без ajax)
Удобство этого варианта в том, что не требуется выполнять ajax запрос. Сначала загружается html c несколькими первыми изображениями, css и js. А по событию ready загружаются оставшиеся изображения, при этом браузер осуществляет запрос только статики.

Этот простой вариант, использует банальную подстановку url-ов изображений в значения атрибутов src для тегов img еще не загруженных изображений.
Серверный скрипт (PHP):

<?php
    // ...
    $output = "<ul>";
    $i = 1;
    $j = 3; // количество изображений для начальной загрузки
    foreach ($images as $image) {
        $attr = $i > $j ? 'img' : 'src';
        $output .= "<li><img ".$attr."='".$image['filepath']."' alt='".$image['title']."' title='".$image['title']."'/></li>";
        $i++;
    }
    $output .= "</ul>";
    // ...
?>

Получам следующий html:

<div id="slider">
    <ul style="width: 6860px; margin-left: 0px;">
        <li><img title="Image1" alt="Image1" src="/images/image1.jpg"></li>
        <li><img title="Image2" alt="Image2" src="/images/image2.jpg"></li>
        <li><img title="Image3" alt="Image3" src="/images/image3.jpg"></li>
        <li><img title="Image4" alt="Image4" img="/images/image4.jpg"></li>
        <li><img title="Image5" alt="Image5" img="/images/image5.jpg"></li>
        <li><img title="Image6" alt="Image6" img="/images/image6.jpg"></li>
        <li><img title="Image7" alt="Image7" img="/images/image7.jpg"></li>
    </ul>
</div>

У последних изображений вместо атрибута src атрибут img.
И к примеру такой css:

#slider{
        width:980px;
        height:613px;
        position:relative;
        overflow: hidden;
}
#slider ul {
        position: absolute;
}
#slider ul li {
        float: left;
        height: 613px;
        list-style-image: none;
        list-style-type: none;
        width: 980px;
        position: relative;
}

Вариант удобен тем, что позволяет использовать готовые jQuery плагины. Собственно так может выглядеть js:

$(function() {
    // функция замены атрибута img на src
    var changeAttr = function(){
        $("#slider ul li img[img]").each(function(){
            $(this).attr("src",$(this).attr("img")).removeAttr("img");
        })
    }
    // подключаем slider плагин
    // который каждые n секунд уменьшает значение margin-left у тега ul
    $("#slider").slider({
        // свойства плагина
    });
    // устанавливаем паузу 2 сек, после чего заменяем атрибуты img на src
    setTimeout(function(){
        changeAttr()}, 
        2000);
})

Этот вариант мне как-то больше понравился и он достаточно четко работает, даже без проверки загрузки изображений. Загружать можно не все оставшиеся изображения, а частями. А если все таки нужно убедиться в полной загрузке картинок, то можно использовать код выше перед выполнением анимации «слайдера». При использовании nginx в качестве фронтенда, можно значительно ускорить получение статики.


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.