Доброго времени суток дорогие разработчики.
Пытаюсь создать слайдер. Идея заключается в том, чтобы картинки, используемые в слайдере, загружались не сразу, а только перед их запросом на отображение.
Контейнер для картинки имеет следующий вид:
<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 загрузки картинки.
Готов рассмотреть другой подход к загрузке изображений. Спасибо всем кто откликнется!