Определенный лучший способ предварительной загрузки изображений с помощью JavaScript/jQuery?
Я полностью осознаю, что этот вопрос задан и ответил везде, как на SO, так и выключен. Однако каждый раз, когда кажется, что существует другой ответ, например. this, и .
Мне все равно, использует ли он jQuery или нет - что важно, что он работает, и кросс-браузер.]
Итак, каков наилучший способ предварительной загрузки изображений?
Ответы
Ответ 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.
Ответ 8
Смотрите это:
http://www.mattfarina.com/2007/02/01/preloading_images_with_jquery
Связанный вопрос о SO:
скрытая предварительная загрузка jquery