Как загружать изображения динамически (или лениво), когда пользователи просматривают их в виде

Я заметил это на многочисленных "современных" веб-сайтах (например, facebook и google image search), где изображения, расположенные ниже сбрасывания, только тогда, когда пользователь прокручивает страницу вниз, чтобы привести их в видимую область видового экрана (на просмотреть страницу, на странице отображается X число тегов <img>, но они не отображаются с сервера сразу). Как называется этот метод, как он работает и сколько браузеров работает. И есть ли плагин jQuery, который может добиться такого поведения при минимальном кодировании.

Изменить

Бонус: может кто-нибудь объяснить, есть ли "onScrolledIntoView" или подобное событие для HTML-элементов. Если нет, как работают эти плагины?

Ответ 1

Некоторые из ответов здесь приведены для бесконечной страницы. То, о чем спрашивает Салман, - это ленивая загрузка изображений.

Плагин

Демо-версия

EDIT: Как работают эти плагины?

Это упрощенное объяснение:

  • Найдите размер окна и найдите положение всех изображений и их размеры.
  • Если изображение не находится в пределах размера окна, замените его на заполнитель того же размера
  • Когда пользователь прокручивается вниз и положение изображения < прокрутка + высота окна, изображение загружается

Ответ 2

Дэйв Арц из AOL дал отличную беседу об оптимизации на jQuery Conference Boston в прошлом году. AOL использует инструмент Sonar для загрузки по требованию в зависимости от положения прокрутки. Проверьте код для сведений о том, как он сравнивает scrollTop (и другие) со смещением элемента, чтобы определить, видима ли часть или весь элемент.

jQuery Sonar

Дэйв рассказывает о сонаре в этих слайдах. Сонар запускается на слайде 46, а общая дискуссия "загрузка по требованию" начинается с слайда 33.

Ответ 3

Существует довольно красивый бесконечный плагин прокрутки здесь

Я никогда не программировал его сам, но я бы предположил, что так оно и работает.

  • Событие связано с прокруткой окна

    $(window).scroll(myInfinteScrollFunction);
    
  • Вызываемая функция проверяет, превышает ли размер прокрутки размер окна

    function myInfiniteScrollFunction() {  
        if($(window).scrollTop() == $(window).height())  
        makeAjaxRequest();  
    }
    
  • Выполняется запрос AJAX, указывающий, какой результат # начать, сколько нужно захватить, и любые другие параметры, необходимые для вытягивания данных.

    $.ajax({
        type: "POST",
        url:  "myAjaxFile.php",
        data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
        success: myInfiniteLoadFunction(msg)
    });
    
  • ajax возвращает некоторый (наиболее вероятный JSON-форматированный) контент и передает их в функцию loadnig.

Надеюсь, что это имеет смысл.

Ответ 4

Я придумал свой собственный базовый метод, который, кажется, работает нормально (до сих пор). Наверное, есть десяток вещей, на которые ссылаются некоторые популярные сценарии, о которых я не думал.

Примечание. Это решение выполняется быстро и легко, но, конечно же, не очень важно для производительности. Определенно загляните в новый обозреватель Intersection Observer, упомянутый Apoorv и объясненный developers.google, если производительность является проблемой.

JQuery

$(window).scroll(function() {
    $.each($('img'), function() {
        if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
            var source = $(this).data('src');
            $(this).attr('src', source);
            $(this).removeAttr('data-src');
        }
    })
})

Пример html-кода

<div>
    <img src="" data-src="pathtoyour/image1.jpg">
    <img src="" data-src="pathtoyour/image2.jpg">
    <img src="" data-src="pathtoyour/image3.jpg">
</div>

Разъяснения

Когда страница прокручивается, каждое изображение на странице проверяется.

$(this).attr('data-src') - если изображение имеет атрибут data-src

и как далеко эти изображения находятся в нижней части окна.

$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)

настройте + 100 на все, что вам нравится (например, 100)

var source = $(this).data('src'); - получает значение data-src= aka URL-адрес изображения

$(this).attr('src', source); - помещает это значение в src=

$(this).removeAttr('data-src'); - удаляет атрибут data-src (поэтому ваш браузер не тратит ресурсы на использование уже загруженных изображений)

Добавление к существующему коду

Чтобы преобразовать ваш html, в редактор просто выполните поиск и замените src=" src="" data-src="

Ответ 5

Ленивые загрузки изображений с помощью добавления прослушивателя для прокрутки событий или использования setInterval очень неактивны, поскольку каждый вызов метода getBoundingClientRect() заставляет браузер повторно перепечатывать всю страницу и введет значительную часть вашего сайта.

Используйте Lozad.js (всего 569 байт без зависимостей), который использует IntersectionObserver для ленивой загрузки изображений.

Ответ 6

Швейцарский армейский нож с изображением ленивой загрузки - это YUI ImageLoader.

Потому что эта проблема больше, чем просто просмотр положения прокрутки.

Ответ 7

Im, использующий jQuery Lazy. Мне потребовалось около 10 минут, чтобы проверить, и час или два, чтобы добавить к большей части ссылок на одном из моих сайтов (CampusCube). У меня есть NO (none/zero) связь любого типа с dev, но это сэкономило мне много времени и в основном помогло улучшить показатель отказов для мобильных пользователей, и я ценю это.

Ответ 8

Эта ссылка работает для меня демо

1. Загрузите плагин jQuery loadScroll после библиотеки jQuery, но до закрытия тега body.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>

2. Добавьте изображения на свою веб-страницу, используя атрибут html5 data-src. Вы также можете вставить заполнители, используя обычный атрибут img src.

<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">

3. Поместите плагин на теги img и укажите длительность эффекта fadeIn при появлении ваших изображений

$('img').loadScroll(500); // in ms