698 votes

Préchargement des images avec jQuery

Je suis à la recherche d'un moyen rapide et facile de précharger des images avec JavaScript. J'utilise jQuery si c'est important.

J'ai vu cela 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, ça a l'air un peu exagéré pour ce que je veux !

Je sais qu'il existe des plugins jQuery qui font cela 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 !

11 votes

$.each(arguments,function(){(new Image).src=this});

977voto

James Points 56229

Rapidement et facile :

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

0 votes

Comment se fait-il que ce code ne fonctionne pas pour moi ? Est-ce qu'il fonctionne pour d'autres personnes ?

26 votes

L'élément image ne doit-il pas être inséré dans le DOM pour que le navigateur le mette en cache ?

1 votes

@JoshNaro Il les charge dans le DOM à l'endroit suivant $('<img />')

106voto

Dennis Rongo Points 2772

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

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

39 votes

hide() est plus laconique que css('display', 'none') .

6 votes

Quel est l'avantage de les insérer dans le DOM ?

0 votes

J'aimerais également connaître l'avantage de les insérer dans le DOM.

55voto

Gajus Kuizinas Points 4713

Faites ce qu'il faut, utilisez JavaScript Objet de l'image . Cette fonction vous permet de déclencher un callback lors du chargement de toutes les images. Cependant, notez qu'elle ne déclenchera jamais de callback si au moins une ressource n'est pas chargée. Ceci peut être facilement corrigé en implémentant onerror et l'incrémentation loaded ou le traitement de l'erreur.

var preload_pictures    = function(picture_urls, callback)
{
    var loaded  = 0;

    for(var i = 0, j = picture_urls.length; i < j; i++)
    {
        var img     = new Image();

        img.onload  = function()
        {                               
            if(++loaded == picture_urls.length && callback)
            {
                callback();
            }
        }

        img.src = picture_urls[i];
    }
};

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

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

4 votes

Faites ce qu'il faut, utilisez l'objet JavaScript Image. avez-vous observé des personnes faisant le mauvais dans ces réponses ?

0 votes

Excellent code. Ai-je raison de penser que cela va déclencher la fonction onload même si l'image est mise en cache ? (Parce que img.onload est déclaré en premier). C'est ce que mes tests ont montré.

3 votes

@alex potentiellement, oui. Si le but est de précharger (ce qui suggère un ordre de performance) alors je préférerais voir une option JS brute plutôt que des options dépendantes de jQuery.

35voto

Dave Points 1080

JP, Après avoir vérifié votre solution, j'avais toujours des problèmes dans Firefox où il ne préchargeait pas les images avant de passer au chargement de la page. J'ai découvert cela en mettant des sleep(5) dans mon script côté serveur. J'ai mis en œuvre la solution suivante basée sur la vôtre qui semble résoudre ce problème.

En fait, j'ai ajouté une fonction de rappel à votre plugin de préchargement jQuery, afin qu'il soit appelé une fois que toutes les images sont 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 curiosité, dans mon contexte, je l'utilise comme suit :

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

J'espère que cela aidera quelqu'un qui arrive sur cette page depuis Google (comme moi) et qui cherche une solution pour précharger des images lors d'appels Ajax.

2 votes

Pour ceux qui n'ont pas envie d'abîmer le prototype de Array, vous pouvez le faire : checklist = this.length Et dans la fonction onload : checklist-- Ensuite : if (checklist == 0) callback();

3 votes

Tout irait bien, mais l'ajout de nouvelles méthodes ou la suppression de méthodes existantes à un objet qui ne vous appartient pas est l'une des pires pratiques en JavaScript.

0 votes

C'est bien et rapide, mais ce code ne déclenchera jamais le rappel si l'une des images est cassée ou incapable de se charger.

25voto

rkcell Points 358

Ce code jQuery d'une ligne crée (et charge) un élément DOM img sans le montrer :

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

4 votes

@huzzah - Vous feriez peut-être mieux de n'utiliser que des sprites. Moins de demandes http. :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X