Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #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.
Ответить с цитированием
  #2 (permalink)  
Старый 06.06.2017, 13:21
Интересующийся
Отправить личное сообщение для Kyjek Посмотреть профиль Найти все сообщения от Kyjek
 
Регистрация: 06.06.2017
Сообщений: 13

Спасибо.
Пример 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!'); }));

Вообще крашится на получении ширины экрана. Я если честно даже не понимаю почему.
Но люди же как то получают рисуют % загрузки фото, как это сделать?
Ответить с цитированием
  #3 (permalink)  
Старый 06.06.2017, 13:59
Интересующийся
Отправить личное сообщение для Kyjek Посмотреть профиль Найти все сообщения от Kyjek
 
Регистрация: 06.06.2017
Сообщений: 13

Потому что когда я ищу плагины загрузки изображений, они как то получают и % и картинки показываются только после полной отрисовки.

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

Я вижу связь. Что картинка уже вся загрузилась и я теряю над ней всяческий контроль. событие onload произошло и все весь js считает что картинка загрузилась. То что она долго отрисовывается на экране это уже не проблема сети браузера и т.д. это полностью клиенская задача. Маленькие картинки не имеют таких проблем, да и использовать я буду восновном их, не более 100-400KB.
Что касается сторонних то например в lazyload картинка не отображается пока полностью не отрисуется, в дурацких так же как и у меня вылезает по строчкам.
Возможно стронние скрипты имеют более сложный функционал. За счет чего они этого добиваются.
Ответить с цитированием
  #5 (permalink)  
Старый 06.06.2017, 14:33
Интересующийся
Отправить личное сообщение для Kyjek Посмотреть профиль Найти все сообщения от Kyjek
 
Регистрация: 06.06.2017
Сообщений: 13

Работает как надо на ура
<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>
Ответить с цитированием
  #6 (permalink)  
Старый 06.06.2017, 15:07
Интересующийся
Отправить личное сообщение для Kyjek Посмотреть профиль Найти все сообщения от Kyjek
 
Регистрация: 06.06.2017
Сообщений: 13

https://jsfiddle.net/Kyjek/ut4xmk56/1/

Да на глаз. При больших обьемах это видно. Открытого Коллбэка нет поэтому меня и не устраивает этот скрипт.

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

https://jsfiddle.net/Kyjek/ut4xmk56/5/

изменил на огромное фото http://luxfon.com/images/201505/luxfon.com_35100.jpg
оно очень долго рисуется.

Собсвенное весь код перед глазами. но что он делает я сходу не пойму ))

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

Чего же тут не понять. Картинка в примере https://jsfiddle.net/Kyjek/ut4xmk56/5/
отображается сразу полностью. от верха до низа. не полосками (по полсочке). Мне надо понять как. Код есть но сложный. Совственно это все.

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

Проанализировал код 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.
Подскажите как отловить событие смены картинок и если можно немного пояснните как загружается изображение.
Ответить с цитированием
  #10 (permalink)  
Старый 07.06.2017, 11:11
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

.attr("src", original) - старт загрузки
.bind("load"... - окончание загрузки
$self.one("appear"... определение момента загрузки (прокручено до изображения, "ленивая загрузка")
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Автоматическая смена картинок через заданное время herotic Элементы интерфейса 45 15.05.2020 16:44
Loading Image на JS exec Ваши сайты и скрипты 10 05.04.2017 20:08
Jquery Upload image & PHP capscom jQuery 0 17.10.2011 17:06
jQuery Image Scroller dolfik Элементы интерфейса 0 31.03.2011 01:03
Jquery doctype + ie8 alizid Internet Explorer 5 21.08.2010 13:39