Так много кода для такой простой задачи

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

Я видел это здесь (Http: //nettuts.com ...):

function complexLoad(config, fileNames) {
  for (var x = 0; x < fileNames.length; x++) {
    $("<img>").attr({
      id: fileNames[x],
      src: config.imgDir + fileNames[x] + config.imgFormat,
      title: "The " + fileNames[x] + " nebula"
    }).appendTo("#" + config.imgContainer).css({ display: "none" });
  }
};

Но это выглядит немного чрезмерно для того, что я хочу!

Я знаю, что есть плагины jQuery, которые делают это, но все они кажутся немного большими (по размеру); Мне просто нужен быстрый, простой и короткий способ предварительной загрузки изображений!

 David Hellsing29 авг. 2012 г., 18:03
$.each(arguments,function(){(new Image).src=this});

Ответы на вопрос(20)

не показывая его:

$('<img src="img/1.jpg"/>');
 Alex K16 нояб. 2012 г., 17:28
@huzzah - Тебе может быть лучше использовать спрайты. Меньше http запросов. :)

Это работает для меня даже в IE9:

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });
 Kevin B27 мар. 2013 г., 15:27
Это в конечном итоге не удастся из-за кэширования, всегда связывайте событие загрузки перед установкой атрибута src.

который фактически загружает изображения в DOM и скрывает его по умолчанию.

function preload(arrayOfImages) {
    $(arrayOfImages).each(function () {
        $('<img />').attr('src',this).appendTo('body').css('display','none');
    });
}
 Shadowxvii29 авг. 2012 г., 16:12
Это прекрасно работает, когда я пытаюсь сделать это в Firefox, но не с IE9.
 alex22 сент. 2011 г., 04:32
hide() более кратко, чемcss('display', 'none').
 Dennis Rongo04 июл. 2013 г., 20:00
Исходя из моего опыта, предварительная загрузка изображения в DOM позволяет браузеру узнать о его существовании и правильном кэшировании. В противном случае изображение существует только в памяти, которая работает только для одностраничных приложений.
 Pono04 сент. 2013 г., 15:31
@alex При добавлении кbody это будет работать и на мобильном телефоне.
 alex07 мая 2013 г., 23:56
В чем преимущество их вставки в DOM?

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

$("img").each(function(){
    var imgsrc = $(this).attr('src');
    if(imgsrc.match('_th.jpg') || imgsrc.match('_home.jpg')){
      imgsrc = thumbToLarge(imgsrc);
      (new Image()).src = imgsrc;   
    }
});

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

В моем случае страница была полна изображений большого пальца, все названы как image_th.jpg, а все соответствующие большие изображения названы image_lg.jpg. Большой палец просто заменяет _th.jpg на _lg.jpg, а затем предварительно загружает все большие изображения.

Надеюсь, это кому-нибудь поможет.

$.fn.preload = function (callback) {
  var length = this.length;
  var iterator = 0;

  return this.each(function () {
    var self = this;
    var tmp = new Image();

    if (callback) tmp.onload = function () {
      callback.call(self, 100 * ++iterator / length, iterator === length);
    };

    tmp.src = this.src;
  });
};

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

$('img').preload(function(perc, done) {
  console.log(this, perc, done);
});

http://jsfiddle.net/yckart/ACbTK/

 robsch02 янв. 2017 г., 09:12
Некоторые поясняющие слова были бы хорошими.
 yckart10 окт. 2013 г., 01:09
@Manticore исправил это ...
 sleepycal24 янв. 2014 г., 17:08
Это действительно хороший ответ, он действительно должен быть лучшим ответом imho.

display:none; правило, а затем показать их, когда вы хотите с JS или JQuery

не используйте функции js или jquery для предварительной загрузки - это просто правило css против множества строк j, которые нужно выполнить

пример: HTML

<img src="someimg.png" class="hide" alt=""/>

Css:

.hide{
display:none;
}

JQuery:

//if want to show img 
$('.hide').show();
//if want to hide
$('.hide').hide();

Предварительная загрузка изображений с помощью jquery / javascript не годится, поскольку загрузка изображений на странице занимает несколько миллисекунд + у вас есть миллисекунды для синтаксического анализа и выполнения сценария, особенно если это большие изображения, поэтому скрытие их в hml лучше также для производительности, потому что изображение действительно предварительно загружено, не будучи видимым, пока вы не покажете это!

 gdelfino30 апр. 2012 г., 02:00
Более подробную информацию об этом подходе можно найти здесь:perishablepress.com/...
 user24664501 февр. 2013 г., 10:18
Но вы должны знать, что этот метод имеет существенный недостаток: ваша страница не будет полностью загружена, пока не будут загружены все изображения. В зависимости от количества загружаемых изображений и их размера это может занять некоторое время. Еще хуже, если тег <img> не определяет высоту и ширину, некоторые браузеры могут подождать, пока изображение будет извлечено, прежде чем отображать остальную часть страницы.
 Germstorm27 мая 2013 г., 10:14
Мне нужно было очень быстрое решение для очень сложного проекта, и на этом все.
 itsme01 февр. 2013 г., 10:47
Кроме того, я действительно думаю, что создание HTML-тегов с помощью Javascript не читается вообще только мои 2 цента
 itsme01 февр. 2013 г., 10:46
@ Алекс, в любом случае вам нужно загрузить IMG, вы можете выбрать, загружать ли его с помощью html и избегать моргания или загрузки половинных изображений, или если вы хотите получить более высокую скорость для нестабильного решения
Решение Вопроса

Быстрыйа также легко:

function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        $('<img/>')[0].src = this;
        // Alternatively you could use:
        // (new Image()).src = this;
    });
}

// Usage:

preload([
    'img/imageName.jpg',
    'img/anotherOne.jpg',
    'img/blahblahblah.jpg'
]);

Или, если вы хотите плагин jQuery:

$.fn.preload = function() {
    this.each(function(){
        $('<img/>')[0].src = this;
    });
}

// Usage:

$(['img1.jpg','img2.jpg','img3.jpg']).preload();
 JoshNaro11 февр. 2011 г., 16:30
я верю$('<img />') просто создает элемент изображения в памяти (см.ссылка). Это выглядит как'$('<img src="' + this + '" />') будет на самом деле создать элемент в скрытом DIV, потому что это более «сложный». Однако я не думаю, что это необходимо для большинства браузеров.
 sparebytes04 февр. 2013 г., 23:01
@RegionalC - может быть немного безопаснее установитьload событие перед установкойsrc на случай, если изображение завершит загрузку до того, как будет установлено событие загрузки?$('<img/>').load(function() { /* it's loaded! */ }).attr('src', this);
 alex17 янв. 2012 г., 03:56
Это странный способ написания плагина jQuery. Почему нет$.preload(['img1.jpg', 'img2.jpg']) ?
 JoshNaro17 авг. 2010 г., 17:33
Не нужно ли вставлять элемент изображения в DOM, чтобы браузер кэшировал его?
 Jasper Kennis05 мая 2012 г., 17:35
Обязательно позвоните это внутрь$(window).load(function(){/*preload here*/}); потому что таким образом все изображения в документе загружаются первыми, скорее всего, они нужны в первую очередь.

После проверки вашего решения, у меня все еще были проблемы в Firefox, когда он не загружал изображения до перехода к загрузке страницы. Я обнаружил это, положив некоторыеsleep(5) в моем сценарии на стороне сервера. Я реализовал следующее решение на основе вашего, которое, кажется, решает эту проблему.

По сути, я добавил обратный вызов в ваш плагин предварительной загрузки jQuery, чтобы он вызывался после правильной загрузки всех изображений.

// Helper function, used below.
// Usage: ['img1.jpg','img2.jpg'].remove('img1.jpg');
Array.prototype.remove = function(element) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == element) { this.splice(i,1); }
  }
};

// Usage: $(['img1.jpg','img2.jpg']).preloadImages(function(){ ... });
// Callback function gets called after all images are preloaded
$.fn.preloadImages = function(callback) {
  checklist = this.toArray();
  this.each(function() {
    $('<img>').attr({ src: this }).load(function() {
      checklist.remove($(this).attr('src'));
      if (checklist.length == 0) { callback(); }
    });
  });
};

Из интереса, в моем контексте, я использую это следующим образом:

$.post('/submit_stuff', { id: 123 }, function(response) {
  $([response.imgsrc1, response.imgsrc2]).preloadImages(function(){
    // Update page with response data
  });
});

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

 MiniGod15 июл. 2012 г., 02:35
Для тех, кто не заинтересован в путанице с Array.prototype, вы можете сделать:checklist = this.length И в функции загрузки:checklist-- Затем:if (checklist == 0) callback();
 SammyK30 окт. 2012 г., 07:38
Красиво и быстро, но этот код никогда не вызовет обратный вызов, если одно из изображений не работает или не может быть загружено.
 Kevin B27 мар. 2013 г., 15:31
.attr({ src: this }).load(function() {...}) должно быть.load(function() {...}).attr({ src: this }) в противном случае у вас будут проблемы с кэшированием.
 Rihards10 сент. 2012 г., 09:17
Все было бы хорошо, однако добавление новых или удаление существующих методов для объекта, которым вы не владеете, является одной из худших практик в JavaScript.

так что вот моя. Он добавляет скрытый элемент div к телу и заполняет его необходимыми изображениями. Я написал это в Coffee Script. Вот Кофе, нормальный js и сжатый js.

Кофе:

$.fn.preload = () ->
    domHolder = $( '<div/>' ).hide()
    $( 'body' ).append domHolder
    this.each ( i, e) =>
        domHolder.append( $('<img/>').attr('src', e) )

Обычный:

(function() {

  $.fn.preload = function() {
    var domHolder,
      _this = this;
    domHolder = $('<div></div>').css('display', 'none');
    $('body').append(domHolder);
    return this.each(function(i, e) {
      return domHolder.append($('<img/>').attr('src', e));
    });
  };

}).call(this);

Сжатый:

function(){$.fn.preload=function(){var a,b=this;return a=$("<div></div>").css("display","none"),$("body").append(a),this.each(function(b,c){return a.append($("<img/>").attr("src",c))})}}.call(this);
 Alexander Kim30 янв. 2014 г., 13:47
Так много кода для такой простой задачи
 jedmao04 июл. 2013 г., 01:40
использование'<div/>' а также.hide() вместо.css('display', 'none')

Это называетсяwaitForImages и он может справитьсяimg элементы или любой элемент со ссылкой на изображение в CSS, например,div { background: url(img.png) }.

Если вы просто хотели загрузитьвсе изображения, в том числе ссылки в CSS, вот как вы это сделаете :)

$('body').waitForImages({
    waitForAll: true,
    finished: function() {
       // All images have loaded.
    }  
});
 alex30 мая 2012 г., 01:44
@DaveCameron Не имеет значения, являются ли изображения видимыми или нет. Вы могли бы легко раскошелиться и внести это изменение - просто добавьте:visible в пользовательский селектор.
 alex28 окт. 2013 г., 03:18
@EleventyOne Проверьте источник относительно пользовательского селектора.
 Philipp Hofmann27 мар. 2014 г., 10:14
@alex Как этот плагин загружает изображения, которые установлены в css on: hover элемента? Это не работает для меня
 Dave Cameron29 мая 2012 г., 21:11
Этот плагин вызывает загрузки изображений, которые еще не появились на странице, или только прикрепляет события к изображениям, которые уже были загружены?
 EleventyOne28 окт. 2013 г., 02:11
Этот плагин выглядит очень интересно. Однакодокументация jquery подчеркивает, чтоload событие, применительно к изображениям: «не работает согласованно и надежно кросс-браузерно». Как плагину удалось обойти это?
    jQuery.preloadImage=function(src,onSuccess,onError)
    {
        var img = new Image()
        img.src=src;
        var error=false;
        img.onerror=function(){
            error=true;
            if(onError)onError.call(img);
        }
        if(error==false)    
        setTimeout(function(){
            if(img.height>0&&img.width>0){ 
                if(onSuccess)onSuccess.call(img);
                return img;
            }   else {
                setTimeout(arguments.callee,5);
            }   
        },0);
        return img; 
    }

    jQuery.preloadImages=function(arrayOfImages){
        jQuery.each(arrayOfImages,function(){
            jQuery.preloadImage(this);
        })
    }
 // example   
    jQuery.preloadImage(
        'img/someimage.jpg',
        function(){
            /*complete
            this.width!=0 == true
            */
        },
        function(){
            /*error*/
        }
    )
 Martijn Pieters♦19 нояб. 2012 г., 15:41
Добро пожаловать в переполнение стека! Вместо того, чтобы публиковать блок кода, пожалуйста,объяснять почему этот код решает поставленную проблему. Без объяснения это не ответ.

кто немного знает ActionScript, вы можете с минимальными усилиями проверить flash player и сделать предварительный загрузчик flash, который вы также можете экспортировать в html5 / Javascript / Jquery. Чтобы использовать, если flash player не обнаружен, посмотрите примеры того, как сделать это с ролью youtube обратно в html5 player :) И создайте свой собственный. У меня нет подробностей, потому что я еще не начал, если я не забыл, я опубликую его позже и попробую какой-то странный код Jquery для моего.

 Usman Ahmed05 мая 2017 г., 19:56
Это не решение. Браузер не поддерживает Flash player по умолчанию. Этого легко добиться с помощью JavaScript, который является родным языком браузера.
 Peter Gruppelaar06 мая 2017 г., 21:06
Кто говорит о Flash? .. где вы, ребята, были ...
 Peter Gruppelaar06 мая 2017 г., 21:08
Я помню Flash ненавистников 2012 года ... это было ненормально ... везде, куда бы я ни пошел, на меня нападали, когда я даже использовал слово Flash.

Объект изображения.

Эта функция позволяет вызвать обратный вызов при загрузке всех изображений. Однако обратите внимание, что он никогда не будет вызывать обратный вызов, если хотя бы один ресурс не загружен. Это можно легко исправить, внедривonerror обратный вызов и увеличениеloaded Значение или обработка ошибки.

var preloadPictures = function(pictureUrls, callback) {
    var i,
        j,
        loaded = 0;

    for (i = 0, j = pictureUrls.length; i < j; i++) {
        (function (img, src) {
            img.onload = function () {                               
                if (++loaded == pictureUrls.length && callback) {
                    callback();
                }
            };

            // Use the following callback methods to debug
            // in case of an unexpected behavior.
            img.onerror = function () {};
            img.onabort = function () {};

            img.src = src;
        } (new Image(), pictureUrls[i]));
    }
};

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('a');
});

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('b');
});
 Startec23 мая 2014 г., 12:06
Блестящий код. Правильно ли я думаю, что это уволитonload событие, даже если изображение кэшируется? (Потому чтоimg.onload объявляется первым). Это то, что показали мои тесты.
 Gajus20 авг. 2014 г., 22:30
@Gazillion дает больше подробностей. Как вы определяете "не работает"? Что такое версия FF?
 Gazillion20 авг. 2014 г., 21:37
Мне понравилось это решение, но я только что обнаружил, что оно не работает в моем Firefox. Это только у меня или у других такая же проблема?
 alex07 мая 2013 г., 23:58
Делайте правильно, используйте JavaScript Image object. Вы наблюдали, как люди делаютнеправильно что в этих ответах?
 Charlie Schliesser16 июл. 2014 г., 01:57
@alex потенциально, да. Если целью является предварительная загрузка (что предполагает порядок производительности), то я бы предпочел видеть необработанный параметр JS вместо зависимых от jQuery.

Я использую следующий код:

$("#myImage").attr("src","img/spinner.gif");

var img = new Image();
$(img).load(function() {
    $("#myImage").attr("src",img.src);
});
img.src = "http://example.com/imageToPreload.jpg";
 Kevin B27 мар. 2013 г., 15:25
Сначала привяжите к событию load, затем установите src.

без плагинов способ предварительно загрузить изображения в jQuery и получить функцию обратного вызова - это создать несколькоimg пометить сразу и посчитать ответы, например,

function preload(files, cb) {
    var len = files.length;
    $(files.map(function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}

preload(["one.jpg", "two.png", "three.png"], function() {
    /* Code here is called once all files are loaded. */
});
​    ​

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

function preload(files, cb) {
    var len = files.length;
    $($.map(files, function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}

чтобы сообщить (современным) веб-браузерам, чтобы они также загружали все соответствующие изображения и кэшировали их. Используйте Grunt и grunt-manifest, чтобы сделать это автоматически, и больше никогда не беспокоиться о скриптах предварительной загрузки, обесценивателях кэша, CDN и т. Д.

https://github.com/gunta/grunt-manifest

imageLoader плагин всего 1,39 КБ

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

$({}).imageLoader({
    images: [src1,src2,src3...],
    allcomplete:function(e,ui){
        //images are ready here
        //your code - site.fadeIn() or something like that
    }
});

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

 Aamir Afridi04 февр. 2013 г., 15:55
неправильное использование $ (document) .ready внутри обратного вызова: |
 Ian05 мар. 2013 г., 20:31
@AamirAfridi Почему это?
 Ian06 мар. 2013 г., 21:27
@AamirAfridi Это не имеет смысла для этой ситуации. Плагин являетсядо погрузчик. Вы хотите выполнить это как можно скорее. И есть множество вещей, которые не зависят от DOM, который вы хотите запустить как можно скорее, итогда когда DOM готов, сделай что-нибудь.
 Ian06 мар. 2013 г., 16:47
@AamirAfridi Нет никаких гарантий, что документ будет готов к обратному вызову ... откуда вы это делаете? Там нет ничего на странице плагина, который говоритallcomplete обратный вызов выполняется после того, как DOM готов. Весьма вероятно, что изображения завершат загрузку после того, как DOM будет готов, но нет никаких оснований предполагать. Я не знаю, почему вы думаете, что обратные вызовы являются магическими и выполняются после того, как DOM будет готов ... вы можете объяснить, откуда вы это взяли? То, что изображения загружены, не означает, что DOM готов
 Aamir Afridi06 мар. 2013 г., 16:09
@Ian, потому что документ уже готов к тому времени, когда сработал обратный вызов. $ (document) .ready используется, чтобы убедиться, что ваш DOM загружен. Когда дело доходит до обратного вызова, это означает, что все изображения загружены, что означает, что ваш DOM загружен, поэтому нет необходимости в document.ready внутри обратного вызова.

5 строк в coffeescript

array = ['/img/movie1..png','/img/movie3.png']

$(document).ready ->
  for index, image of array
    img[index] = new Image()
    img[index].src = image
 Ro Yo Mi10 авг. 2013 г., 02:25
Можете ли вы рассказать о том, как работает решение для решения вопроса в ОП? И, возможно, прокомментируете ваш код, чтобы другие могли его легче понять?
function preload(imgs) {
    $(imgs).each(function(index, value) {
        $('<img />').attr('src', value).appendTo('body').css('display', 'none');
    });
}

.attr('src',value) не.attr('src',this)

просто чтобы указать на это :)

 Oybek28 июл. 2013 г., 10:13
Объемthis внутри обратного вызова, который передается$.each присваивается значению, которое повторяется.
 Whisher29 июл. 2013 г., 14:32
? $ (['img1.jpg', 'img2.jpg', 'img3.jpg']). each (function (index, value) {console.log (value); // img1.jpg console.log (this) ; // String {0 = "i", 1 = "m", 2 = "g", more ...} $ ('<img />'). Attr ('src', this) .appendTo (' body '). css (' display ',' none ');});
 Oybek30 июл. 2013 г., 20:59
Гектометр Я думаю, ты прямо здесь. Например$("div").each(function(i, el){ console.log(el == this);}); генерирует всеtrues; Итерация по массиву, кажется, ведет себя по-другому.

I. Их пример кода просто использует JS для вставки элементов IMG, и поле заполнителя изображения отображается до тех пор, пока изображение не будет загружено. Я нашел ответ здесь, который работал для меня:https://stackoverflow.com/a/10863680/2095698 .

$('<img src="'+ imgPaht +'">').load(function() {
$(this).width(some).height(some).appendTo('#some_target');
});

Это предварительно загружает изображение, как предлагалось ранее, а затем использует обработчик для добавления объекта img после загрузки URL-адреса img. Документация jQuery предупреждает, что кэшированные изображения плохо работают с этим кодом события / обработчика, но он работает для меня в FireFox и Chrome, и мне не нужно беспокоиться об IE.

 Kevin B27 мар. 2013 г., 15:24
Это не будет хорошо работать с кэшированными изображениями, как вы узнали. Обходной путь должен сначала связать событие загрузки, а затем установить атрибут src.

Ваш ответ на вопрос