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 загрузки картинки. Готов рассмотреть другой подход к загрузке изображений. Спасибо всем кто откликнется! |
Спасибо.
Пример http://jsfiddle.net/4fg3K/34/ не работает как надо. Он так же как и мой код пропускает отрисовку.
function checkIfRendered(img, onRender) {
var elRatio = img.width() / img.height();
var natRatio = img.naturalWidth / img.naturalHeight;
if (elRatio === natRatio)
onRender();
else {
setTimeout(function() {
checkIfRendered(img, onRender)
}, 20);
}
}
img.onload(checkIfRendered(img, function() { alert('rendered!'); }));
Вообще крашится на получении ширины экрана. Я если честно даже не понимаю почему. Но люди же как то получают рисуют % загрузки фото, как это сделать? |
Потому что когда я ищу плагины загрузки изображений, они как то получают и % и картинки показываются только после полной отрисовки.
Но Вы правы эток делу не относится. |
Я вижу связь. Что картинка уже вся загрузилась и я теряю над ней всяческий контроль. событие onload произошло и все весь js считает что картинка загрузилась. То что она долго отрисовывается на экране это уже не проблема сети браузера и т.д. это полностью клиенская задача. Маленькие картинки не имеют таких проблем, да и использовать я буду восновном их, не более 100-400KB.
Что касается сторонних то например в lazyload картинка не отображается пока полностью не отрисуется, в дурацких так же как и у меня вылезает по строчкам. Возможно стронние скрипты имеют более сложный функционал. За счет чего они этого добиваются. |
Работает как надо на ура
<img class="lazy" data-original="img/1.jpg" style="width:100%;" >
<script src="jquery-2.2.4.js"></script>
<script src="jquery.lazyload.js?v=1.9.1"></script>
<script type="text/javascript" charset="utf-8">
$(function() {
$("img.lazy").lazyload();
});
</script>
|
https://jsfiddle.net/Kyjek/ut4xmk56/1/
Да на глаз. При больших обьемах это видно. Открытого Коллбэка нет поэтому меня и не устраивает этот скрипт. |
https://jsfiddle.net/Kyjek/ut4xmk56/5/
изменил на огромное фото http://luxfon.com/images/201505/luxfon.com_35100.jpg оно очень долго рисуется. Собсвенное весь код перед глазами. но что он делает я сходу не пойму )) |
Чего же тут не понять. Картинка в примере https://jsfiddle.net/Kyjek/ut4xmk56/5/
отображается сразу полностью. от верха до низа. не полосками (по полсочке). Мне надо понять как. Код есть но сложный. Совственно это все. трафик в 2017 году. сейчас даже на мобильном безлимитный. Покрайнемере у меня :) |
Проанализировал код lazy плагина и выделил часть отвечающую за прорисовку.
Реализованно хитро и совсем не гибко. <img id="img1" data-original="img/2.jpg" src="img/loader.gif" > Есть картинка с изначальной img/loader.gif и пока img/2.jpg не загрузится и не прорисуется она не сменит img/loader.gif.
$(document).ready(function () {
var $self = $('#img1');
$self.one("appear", function () {
var original = $self.data('original');
$("<img />")
.bind("load", function () {
$self.attr("src", original);
})
.attr("src", original);
}).trigger("appear");
});
Надо заметить что работает так как мне нужно, но я не могу отловить момент когда происходит смена картинки. Я бы хотел добавить стиль к загруженной картинке. (например width:100%;) Но так не получается стиль применяется раньше и раздувает img/loader.gif. Подскажите как отловить событие смены картинок и если можно немного пояснните как загружается изображение. |
.attr("src", original) - старт загрузки
.bind("load"... - окончание загрузки $self.one("appear"... определение момента загрузки (прокручено до изображения, "ленивая загрузка") |
| Часовой пояс GMT +3, время: 09:01. |