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

Эти изображения загружаются динамически:

<div id="gallery-images" class="gallery-control">
    <ul>
        <img class="galleryImgs" data-src="images/test-image-1.jpg" src="images/test-image-1-s.jpg" />
        <img class="galleryImgs" data-src="images/test-image-2.jpg" src="images/test-image-2-s.jpg" />
        <img class="galleryImgs" data-src="images/test-image-3.jpg" src="images/test-image-3-s.jpg" />      
    </ul>
</div>

Я пытаюсь предварительно загрузить URL-адреса изображений из атрибута data-src каждого тега img. Это код, который я написал:

$('.galleryImgs').each(function(){
    $('<img/>')[0].src = $(this).attr("data-src");
});

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


person CoreyRS    schedule 25.07.2012    source источник
comment
Проверьте, вызывает ли он какой-либо запрос GET для этих изображений на вашей консоли. Если нет, вы можете попробовать добавить его в DOM внутри контейнера display:none.   -  person Fabrício Matté    schedule 25.07.2012
comment
Я бы использовал каждую функцию следующим образом: $('.galleryImgs').each(function(idx, e) { ... }   -  person anttix    schedule 25.07.2012
comment
Так это не работает? Код выглядит нормально. Я не могу сказать, есть ли у вас реальная проблема или вы просто спрашиваете, все ли в порядке.   -  person j08691    schedule 25.07.2012
comment
на самом деле не могу сказать, работает ли он, потому что, как я уже сказал, сейчас все статично, но после очистки кеша переходы производительности, похоже, улучшились, но, очевидно, я не могу быть полностью уверен, пока не запущу реальный динамический скрипт. Во всяком случае, я воспользуюсь предложением, предоставленным @FabrícioMatté, и просмотрю обновленный источник ajax, чтобы убедиться, что он работает.   -  person CoreyRS    schedule 25.07.2012
comment
О, это была просто быстрая мысль, в любом случае, использование $.get для предварительного кэширования каждого изображения должно работать и в современных браузерах. Я мог бы сделать скрипку для проверки.   -  person Fabrício Matté    schedule 25.07.2012
comment
был бы очень признателен, если бы вы это сделали.   -  person CoreyRS    schedule 25.07.2012
comment
Да, я сказал может, потому что я немного занят сегодня вечером, но я проверю это через пару минут. :P   -  person Fabrício Matté    schedule 25.07.2012
comment
Проблема с $.get заключается в том, что вы не сможете предварительно загружать междоменные изображения.   -  person Fabrício Matté    schedule 25.07.2012
comment
междоменный не будет проблемой, так как все извлекается из того же домена, на котором запускается скрипт.   -  person CoreyRS    schedule 25.07.2012


Ответы (1)


Я сделал быстрый фрагмент с идеей моего первоначального комментария, который должен работать в разных доменах или нет:

$(function() {
    //creates an imgcacher hidden element
    $('<div/>', {id: 'imgcacher', style: 'display:none;'}).appendTo('body');
    var cacher = $('#imgcacher'); //caches the cacher selector

    //appends the images to the DOM for caching
    $('.galleryImgs').each(function(){
        $('<img/>', {src: $(this).data('src'), class: "precachedImg"}).appendTo(cacher);
    });

    //clean up the DOM after the images are fully loaded and cached
    $('.precachedImg').promise().done(function() {
        cacher.remove();
    });
});​

DEMO
Обратите внимание, что второе изображение может быть слишком большой для загрузки за 5 секунд, если ваше соединение недостаточно быстрое, но тогда оно должно быть хотя бы частично загружено.

$.get не работало для кэширования изображений в Chrome, когда я тестировал его, поэтому решение, приведенное выше, является моим предпочтительным. Он прекрасно работает во всех браузерах, которые я тестировал, при любой скорости соединения и размере файла. Современные браузеры будут запрашивать ресурс изображения только один раз и отображать его параллельно со всеми другими дубликатами на странице, не генерируя дополнительных запросов, как запрос ajax.

Кроме того, это динамичное, масштабируемое и чистое решение. Однако, если вы предпочитаете простоту, у конечного пользователя будет «тот же самый» опыт, что и при первоначальном добавлении изображений с display:none в DOM. Очевидно, что это излишне загромождает DOM, поэтому я бы использовал свой фрагмент выше.

Кроме того, вот немного упрощенная версия:

$(function() {
    //appends the images to the DOM for caching
    $('.galleryImgs').each(function(){
        $('<img/>', {src: $(this).data('src'), class: 'precachedImg', style: 'display:none;'}).appendTo('body');
    });

    //clean up the DOM as the images are loaded and cached
    $('.precachedImg').load(function() {
        $(this).remove();
    });
});

Скрипка

person Fabrício Matté    schedule 25.07.2012
comment
Без проблем. =] Я только что сделал немного упрощенную версию, которая гарантирует, что изображение будет полностью загружено перед удалением элемента из DOM, если вы когда-нибудь столкнетесь с проблемами с первым кодом (хотя это не должно происходить в любом современном браузере), или, вы также можете стереть блок очистки, если обнаружите проблемы с каким-либо браузером. - person Fabrício Matté; 25.07.2012