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

Я ищу быстрый и простой способ предварительной загрузки изображений с помощью 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, которые делают это, но все они кажутся немного большими (по размеру); Мне просто нужен быстрый, простой и короткий способ предварительной загрузки изображений!

Ответ 1

Быстро и просто:

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();

Ответ 2

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

function preload(arrayOfImages) {
    $(arrayOfImages).each(function () {
        $('<img />').attr('src',this).appendTo('body').css('display','none');
    });
}

Ответ 3

Использовать JavaScript Объект изображения.

Эта функция позволяет вам вызвать обратный вызов при загрузке всех изображений. Однако обратите внимание, что он никогда не вызовет обратный вызов, если хотя бы один ресурс не загружен. Это можно легко устранить, реализуя обратный вызов 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');
});

Ответ 4

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

В основном я добавил обратный вызов в ваш предварительный плагин 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.

Ответ 5

Этот однострочный код jQuery создает (и загружает) элемент DOM img, не показывая его:

$('<img src="img/1.jpg"/>');

Ответ 6

$.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/

Ответ 7

У меня есть небольшой плагин, который обрабатывает это.

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

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

$('body').waitForImages({
    waitForAll: true,
    finished: function() {
       // All images have loaded.
    }  
});

Ответ 8

этот jquery imageLoader плагин всего 1,39kb

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

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

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

Ответ 9

вы можете загружать изображения в свой html где-нибудь с помощью правила css display:none;, а затем показывать их, когда хотите с js или jquery

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

example: 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 не является хорошей причиной для того, чтобы изображения занимали несколько миллисекунд для загрузки на странице +, вы должны анализировать и выполнять миллисекунды для script, если они большие изображения, поэтому их скрытие в hml лучше также для производительности, потому что изображение действительно предварительно загружено без видимой видимости, пока вы не покажете это!

Ответ 10

Быстрый, без плагинов способ предварительной загрузки изображений в 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();
        }
    });
}

Ответ 11

Спасибо за это! Я хотел бы добавить немного риффа в ответ JP - я не знаю, поможет ли это кому-либо, но таким образом вам не нужно создавать массив изображений, и вы можете предварительно загрузить все свои большие изображения, если вы Назовите правильные пальцы. Это удобно, потому что у меня есть кто-то, кто пишет все страницы в 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, а затем предварительно загружает все большие изображения.

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

Ответ 12

    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*/
        }
    )

Ответ 13

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

$("#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";

Ответ 14

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

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

Ответ 15

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

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });

Ответ 16

Я хотел сделать это с помощью пользовательского наложения API Карт Google. Их примерный код просто использует JS для вставки IMG-элементов, а поле-заполнитель изображения отображается до загрузки изображения. Я нашел здесь ответ, который работал на меня: fooobar.com/questions/12697/....

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

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

Ответ 17

function preload(imgs) {
$(imgs).each(function(index, value){
        $('<img />').attr('src',value).appendTo('body').css('display','none');
    });
}

.attr('src',value)

не

.attr('src',this)

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

Ответ 18

5 строк в coffeescript

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

$(document).ready ->
  for index, image of array
    img[index] = new Image()
    img[index].src = image

Ответ 19

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

Ответ 20

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

Кофе

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

Normal:

(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);