Показать сообщение отдельно
  #1 (permalink)  
Старый 06.06.2017, 09:33
Интересующийся
Отправить личное сообщение для Kyjek Посмотреть профиль Найти все сообщения от Kyjek
 
Регистрация: 06.06.2017
Сообщений: 13

jQuery Image Loading
Доброго времени суток дорогие разработчики.
Пытаюсь создать слайдер. Идея заключается в том, чтобы картинки, используемые в слайдере, загружались не сразу, а только перед их запросом на отображение.
Контейнер для картинки имеет следующий вид:
<div class="slide" id="img1" data-img="img/slide-img/img (0).jpg"></div>

id="img1" - используется только для примера.
data-img="img/slide-img/img (0).jpg" - url изображения
для загрузки мне необходимо отловить события:
1. Загрузки (поместить в div индикатор загрузки )
<i class="fa fa-spinner fa-spin fa-2x" style="display:block;" aria-hidden="true"></i>

2. Ошибки (поместить в div индикатор ошибки )
<i class="fa fa-exclamation-triangle fa-2x" style="display:block;" aria-hidden="true"></i>

3. Готово (Все загрузилось, поместить загруженную картинку в div)
$('#img1').append(image);

Для примера возьмем событие для загрузки: «нажатие на блок».
Добавим обработчик в документ реаду
$('#img1').click(function () {
        var url = $('#img1').data('img');
        $.when(load_img_async(url)).done(function (image)
        {
            $('#img1').append(image);
        });
    });

Вытащим url и подставим его в функцию load_img_async, дождемся когда она выполнится. После чего запихнем картинку в div как написано в пункте 3.
Код функции
function load_img_async(source) {
    return $.Deferred(function (task) {
        var image = new Image();
        image.onload = function ()
        {
            $('#img1').empty();
            task.resolve(image);
        }
        image.onerror = function ()
        {
            $('#img1').empty().append('<i class="fa fa-exclamation-triangle fa-2x" style="display:block;" aria-hidden="true"></i>');
            task.reject();
        }
        $('#img1').empty().append('<i class="fa fa-spinner fa-spin fa-2x" style="display:block;" aria-hidden="true"></i>');
        image.src = source;
        image.className = "slide-img";
    }).promise();
}

Функция создает объект image и вешает два обработчика событий оnload все загружено и onerror ошибка. Далее наш div чистим и помещаем в него fa-spinner. Если ошибка то div чистим и помещаем в него fa-exclamation. Если же оnload все загружено то чистим div и возвращаем готовое изображение, которое будет помещено в этот же div.
Вроде все хорошо и работает, но я беру большую картинку (40мб). И вставляю ее. Загрузка происходит быстро ( ведь лежит в той же папке), но вот ее отрисовка происходит полосками. Предполагаю что $('#img1').append(image); кидает ее в контейнер и да она загружена, но не отрисованна и медленно появляется в контейнере.
Как отловить время отрисовки?
P.s. хотелось бы еще реализовать плавную смену индикатора загрузки, ошибки и картинки в diю
Моя маленькая прихоть получить % или kb загрузки картинки.
Готов рассмотреть другой подход к загрузке изображений. Спасибо всем кто откликнется!

Последний раз редактировалось Kyjek, 06.06.2017 в 09:37.
Ответить с цитированием