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, время: 10:01. |