Précharger les images avec jQuery

je cherche un moyen rapide et facile de précharger des images avec JavaScript. Je suis à l'aide de jQuery si c'est important.

j'ai vu ça ici ( 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" });
  }
};

mais, il semble un peu sur-le-dessus-pour ce que je veux!

je sais qu'il y a des plugins jQuery qui font ça mais ils semblent tous un peu gros (en taille); j'ai juste besoin d'un moyen rapide, facile et court de précharger les images!

664
demandé sur James 2009-01-25 00:25:54

20 réponses

Quick et easy:

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'
]);

ou, si vous voulez un plugin jQuery:

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

// Usage:

$(['img1.jpg','img2.jpg','img3.jpg']).preload();
949
répondu James 2009-01-24 21:28:26

Voici une version modifiée de la première réponse qui charge les images dans DOM et les cache par défaut.

function preload(arrayOfImages) {
    $(arrayOfImages).each(function () {
        $('<img />').attr('src',this).appendTo('body').css('display','none');
    });
}
96
répondu Dennis Rongo 2013-01-22 19:03:38

utiliser JavaScript Image object .

cette fonction vous permet de déclencher un rappel lors du chargement de toutes les photos. Toutefois, notez qu'il ne sera jamais déclencher un rappel si au moins une ressource n'est pas chargé. Cela peut être facilement corrigé en implémentant la valeur onerror callback et incrementing loaded ou en gérant l'erreur.

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');
});
50
répondu Gajus 2015-01-25 12:02:07

JP, après avoir vérifié votre solution, J'avais encore des problèmes avec Firefox où il ne préchargerait pas les images avant de se déplacer avec le chargement de la page. J'ai découvert ceci en mettant un peu de sleep(5) dans mon script côté serveur. J'ai implémenté la solution suivante basée sur la vôtre qui semble résoudre ceci.

fondamentalement j'ai ajouté un callback à votre plugin jQuery preload, pour qu'il soit appelé après que toutes les images soient correctement chargées.

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

par intérêt, dans mon contexte, j'utilise ceci comme suit:

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

espérons que cela aide quelqu'un qui vient à cette page de Google (comme je l'ai fait) à la recherche d'une solution pour précharger les images sur les appels Ajax.

34
répondu Dave 2011-01-22 00:06:19

cette seule ligne jQuery code crée (et charge) un élément DOM img sans l'afficher:

$('<img src="img/1.jpg"/>');
24
répondu rkcell 2012-04-02 21:37:54
$.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;
  });
};

l'usage est assez simple:

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

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

21
répondu yckart 2014-09-08 09:30:25

j'ai un petit plugin qui gère cela.

il est appelé waitForImages et il peut traiter img éléments ou n'importe quel élément avec une référence à une image dans le CSS, par exemple div { background: url(img.png) } .

si vous vouliez simplement charger toutes les images , y compris celles référencées dans le CSS, voici comment vous le feriez:)

$('body').waitForImages({
    waitForAll: true,
    finished: function() {
       // All images have loaded.
    }  
});
19
répondu alex 2012-03-27 10:09:52

vous pouvez charger des images dans votre html quelque part en utilisant la règle css display:none; , puis les montrer quand vous voulez avec js ou jquery

n'utilisez pas les fonctions js ou jquery pour précharger est juste une règle css Vs plusieurs lignes de js à exécuter

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

Précharger les images par jQuery/javascript n'est pas une bonne cause les images prennent quelques millisecondes à charger en page + vous avez des millisecondes pour que le script soit analysé et exécuté, surtout s'il s'agit de grandes images, alors les cacher en hml est mieux aussi pour la performance, car l'image est vraiment préchargée sans être visible du tout, jusqu'à ce que vous le montriez!

13
répondu sbaaaang 2013-05-28 07:51:57

cette jquery imageLoader plugin est juste 1.39 ko

utilisation:

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

Il ya aussi d'autres options comme si vous voulez charger les images de façon synchrone ou asychronously et un événement complet pour chaque image individuelle.

13
répondu alzclarke 2015-08-08 00:26:42

un moyen rapide, sans plugin, de précharger les images dans jQuery et d'obtenir une fonction de rappel est de créer plusieurs img tags à la fois et compter les réponses, par exemple

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

notez que si vous voulez prendre en charge IE7, vous devrez utiliser cette version légèrement moins jolie (qui fonctionne aussi dans d'autres navigateurs):

function preload(files, cb) {
    var len = files.length;
    $($.map(files, function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}
9
répondu izb 2012-06-28 10:42:28

Merci pour cela! Je voudrais ajouter un peu de riff sur la réponse de J-P - Je ne sais pas si cela aidera quelqu'un, mais de cette façon vous n'avez pas à créer un tableau d'images, et vous pouvez précharger toutes vos grandes images si vous nommez vos pouces correctement. C'est pratique parce que j'ai quelqu'un qui écrit toutes les pages en html, et cela garantit une étape de moins pour eux de faire - en éliminant le besoin de créer le tableau d'image, et une autre étape où les choses pourraient se foirer.

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

fondamentalement, pour chaque image sur la page il saisit le src de chaque image, si elle correspond à certains critères (est un pouce, ou image de la page d'accueil) il change le nom(une chaîne de base remplacer dans l'image src), puis charge les images.

dans mon cas la page était pleine d'images miniatures toutes nommées quelque chose comme image_th.jpg, et toutes les grandes images correspondantes sont nommées image_lg.jpg. Le pouce à large remplace le _e.jpg avec _lg.jpg et ensuite de précharge toutes les images de grande taille.

J'espère que ça aidera quelqu'un.

7
répondu dgig 2011-05-26 17:10:05
    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*/
        }
    )
3
répondu Alex 2012-11-19 14:19:17

j'utilise le code suivant:

$("#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";
3
répondu Cristan 2013-03-27 17:58:40

j'utiliserais un fichier manifeste pour indiquer aux navigateurs web (modernes) de charger toutes les images pertinentes et de les mettre en cache. Utilisez Grunt et grunt-manifest pour le faire automatiquement et ne vous inquiétez plus jamais des scripts de préchargement, des invalidateurs de cache, CDN etc.

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

1
répondu Christian Landgren 2014-02-27 06:07:43

cela fonctionne pour moi même dans IE9:

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });
0
répondu Zymotik 2012-10-25 15:18:06

je voulais le faire avec une superposition personnalisée de L'API GoogleMaps. Leur exemple de code utilise simplement JS pour insérer des éléments IMG et la boîte de dialogue image est affichée jusqu'à ce que l'image soit chargée. J'ai trouvé ici une réponse qui a fonctionné pour moi: https://stackoverflow.com/a/10863680/2095698 .

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

ceci précharge une image comme suggéré précédemment, puis utilise le gestionnaire pour ajouter l'objet img après que l'URL img soit chargée. jQuery la documentation avertit que les images mises en cache ne fonctionnent pas bien avec ce code de concours complet/handler, mais cela fonctionne pour moi dans FireFox et Chrome, et je n'ai pas à me soucier de IE.

0
répondu bwinchester 2017-05-23 12:26:35
function preload(imgs) {
$(imgs).each(function(index, value){
        $('<img />').attr('src',value).appendTo('body').css('display','none');
    });
}

.attr('src',value)

pas

.attr('src',this)

juste à point :)

-1
répondu Whisher 2013-07-30 19:00:21

5 lignes dans 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
-1
répondu Guy Morita 2013-08-09 23:56:52

pour ceux qui connaissent un peu actionscript, vous pouvez vérifier pour flash player, avec un effort minimal, et faire un pré-chargeur flash, que vous pouvez également exporter vers html5/Javascript/Jquery. Pour utiliser si le lecteur flash n'est pas détecté, vérifiez les exemples sur la façon de le faire avec le rôle youtube retour au lecteur html5:) Et de créer votre propre. Je n'ai pas les détails, parce que je n'ai pas encore commencé, si je n'ai pas oublié, je wil post plus tard et essayer un certain standard Jquery code de la mine.

-3
répondu Peter Gruppelaar 2015-06-13 10:19:30

tous les hipsters ont écrit leur propre version, donc voici la mienne. Il ajoute un div caché pour le corps et le remplit avec les images. Je l'ai écrit dans un scénario de café. Voici le café, le js normal, et le JS comprimé.

café:

$.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);

comprimé:

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);
-7
répondu Jasper Kennis 2013-07-08 10:37:21