Определенный лучший способ предварительной загрузки изображений с помощью JavaScript/jQuery? - программирование
Подтвердить что ты не робот

Определенный лучший способ предварительной загрузки изображений с помощью JavaScript/jQuery?

Я полностью осознаю, что этот вопрос задан и ответил везде, как на SO, так и выключен. Однако каждый раз, когда кажется, что существует другой ответ, например. this, и .

Мне все равно, использует ли он jQuery или нет - что важно, что он работает, и кросс-браузер.]

Итак, каков наилучший способ предварительной загрузки изображений?

4b9b3361

Ответ 1

К сожалению, это зависит от вашей цели. Если вы планируете использовать изображения в целях стиля, лучше всего использовать спрайты. http://www.alistapart.com/articles/sprites2

Однако, если вы планируете использовать изображения в <img> теги, то вы захотите предварительно загрузить их с помощью

function preload(sources)
{
  var images = [];
  for (i = 0, length = sources.length; i < length; ++i) {
    images[i] = new Image();
    images[i].src = sources[i];
  }
}

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

с помощью new Image() не связано с расходами на использование методов DOM, но новый запрос для указанного изображения будет добавлен в очередь. Поскольку изображение, на данный момент, фактически не добавлено на страницу, не связано с повторным рендерингом. Я бы рекомендовал, однако, добавить это в конец вашей страницы (так как все ваши сценарии должны быть, когда это возможно), чтобы не допустить, чтобы он удерживал более критические элементы.

Изменить: Отредактировано, чтобы правильно отразить комментарий, указывая, что для работы требуются отдельные объекты Image. Спасибо, и мой плохой, чтобы не проверить его более внимательно.

Edit2: отредактирован, чтобы сделать повторное использование более очевидным

Редактировать 3 (3 года спустя):

Из-за изменений в том, как браузеры обрабатывают невидимые изображения (отображение: нет или, как в этом ответе, никогда не добавляется к документу), предпочтительным является новый подход к предварительной загрузке.

Вы можете использовать запрос Ajax для принудительного раннего извлечения изображений. Использование jQuery, например:

jQuery.get(source);

Или в контексте нашего предыдущего примера вы можете сделать:

function preload(sources)
{
  jQuery.each(sources, function(i,source) { jQuery.get(source); });
}

Обратите внимание, что это не относится к случаю спрайтов, которые являются точными как-есть. Это просто для вещей, таких как фотогалереи или слайдеры/карусели с изображениями, где изображения не загружаются, потому что они не видны изначально.

Также обратите внимание, что этот метод не работает для IE (ajax обычно не используется для извлечения данных изображения).

Ответ 2

спрайтов

Как уже упоминалось, написание работает довольно хорошо по целому ряду причин, однако оно не так хорошо, как это было сделано.

  • В верхней части вы делаете только один HTTP-запрос для своих изображений. YMMV, хотя.
  • В нижней части вы загружаете все в один HTTP-запрос. Поскольку большинство современных браузеров ограничены двумя параллельными соединениями, запрос на изображение может блокировать другие запросы. Следовательно, YMMV и что-то вроде фона вашего меню могут не отображаться немного.
  • Несколько изображений имеют одну и ту же цветовую палитру, поэтому есть некоторая экономия, но это не всегда так, и даже это незначительно.
  • Сжатие улучшено, потому что между изображениями есть более общие данные.

Работа с нерегулярными фигурами сложна. Сочетание всех новых изображений с новыми - еще одно раздражение.

Подход с низким гнездом с использованием <img> теги

Если вы ищете решение наиболее окончательное, тогда вы должны пойти с подходом с низким уровнем доступа, который я по-прежнему предпочитаю. Создать <img> ссылки на изображения в конце вашего документа и установите width и height на 1x1 пиксель и дополнительно поместите их в скрытый div. Если они находятся в конце страницы, они будут загружены после другого содержимого.

Ответ 3

По состоянию на январь 2013 года ни один из описанных здесь методов не работал, поэтому здесь вместо этого было протестировано и работает с Chrome 25 и Firefox 18. Использует jQuery и этот плагин, чтобы обойти причуды события загрузки:

function preload(sources, callback) {
    if(sources.length) {
        var preloaderDiv = $('<div style="display: none;"></div>').prependTo(document.body);

        $.each(sources, function(i,source) {
            $("<img/>").attr("src", source).appendTo(preloaderDiv);

            if(i == (sources.length-1)) {
                $(preloaderDiv).imagesLoaded(function() {
                    $(this).remove();
                    if(callback) callback();
                });
            }
        });
    } else {
        if(callback) callback();
    }
}

Использование:

preload(['/img/a.png', '/img/b.png', '/img/c.png'], function() { 
    console.log("done"); 
});

Обратите внимание, что вы получите смешанные результаты, если кеш отключен, который по умолчанию включен в Chrome, когда инструменты разработчика открыты, поэтому имейте это в виду.

Ответ 4

По моему мнению, использование Multipart XMLHttpRequest, представленное некоторыми библиотеками, будет предпочтительным решением в последующие годы. Однако IE < v8, по-прежнему не поддерживают данные: uri (даже IE8 имеет ограниченную поддержку, позволяя до 32kb). Ниже приведена реализация предварительной загрузки параллельных изображений - http://code.google.com/p/core-framework/wiki/ImagePreloading, которая входит в рамки, но все же стоит взглянуть.

Ответ 5

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

Мое решение было еще более простым.

Я просто использовал CSS.

#hidden_preload {
    height: 1px;
    left: -20000px;
    position: absolute;
    top: -20000px;
    width: 1px;
}

Ответ 6

Здесь идет мое простое решение с постепенным исчезновением изображения после его загрузки.

    function preloadImage(_imgUrl, _container){
        var image = new Image();
            image.src = _imgUrl;
            image.onload = function(){
                $(_container).fadeTo(500, 1);
            };
        }

Ответ 7

В моем случае использования у меня была карусель с полноэкранными изображениями, которые я хотел предварительно загрузить. Однако, поскольку изображения отображаются в порядке и могут занять несколько секунд для загрузки, важно, чтобы я загружал их по порядку, последовательно.

Для этого я использовал метод async library waterfall() (https://github.com/caolan/async#waterfall)

        // Preload all images in the carousel in order.
        image_preload_array = [];
        $('div.carousel-image').each(function(){
            var url = $(this).data('image-url');
            image_preload_array.push(function(callback) {
                var $img = $('<img/>')
                $img.load(function() {
                    callback(null);
                })[0].src = url;
            });
        });
        async.waterfall(image_preload_array);

Это работает, создавая массив функций, каждой функции передается параметр callback(), который он должен выполнить, чтобы вызвать следующую функцию в массиве. Первым параметром callback() является сообщение об ошибке, которое выйдет из последовательности, если предоставляется ненулевое значение, поэтому мы каждый раз пропускаем null.