Pull to refresh

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

Lumber room
Awaiting invitation
На страницах современных сайтов, очень часто требуется организовать фотогалерею, слайд шоу, «карусельку» и 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 в качестве фронтенда, можно значительно ускорить получение статики.

Tags:
Hubs:
You can’t comment this post because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.