Precaricamento delle immagini con jQuery

Sto cercando un modo facile e veloce per precaricare le immagini con JavaScript. Sto usando jQuery se è importante.

Ho visto questo qui ( http: //nettuts.com … ):

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

Ma sembra un po ‘esagerato per quello che voglio!

So che ci sono plugin jQuery che fanno questo, ma sembrano tutti un po ‘grandi (in termini di dimensioni); Ho solo bisogno di un modo rapido, facile e breve per il precaricamento delle immagini!

Veloce e facile:

 function preload(arrayOfImages) { $(arrayOfImages).each(function(){ $('')[0].src = this; // Alternatively you could use: // (new Image()).src = this; }); } // Usage: preload([ 'img/imageName.jpg', 'img/anotherOne.jpg', 'img/blahblahblah.jpg' ]); 

Oppure, se vuoi un plugin jQuery:

 $.fn.preload = function() { this.each(function(){ $('')[0].src = this; }); } // Usage: $(['img1.jpg','img2.jpg','img3.jpg']).preload(); 

Ecco una versione ottimizzata della prima risposta che carica effettivamente le immagini in DOM e la nasconde di default.

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

Usa l’ object immagine JavaScript.

Questa funzione consente di triggersre una richiamata al caricamento di tutte le immagini. Tuttavia, si noti che non attiverà mai una richiamata se almeno una risorsa non viene caricata. Questo può essere facilmente risolto implementando la callback di onerror e incrementando il valore loaded o gestendo l’errore.

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

JP, Dopo aver verificato la tua soluzione, stavo ancora avendo problemi in Firefox, dove non avrebbe precaricato le immagini prima di spostarsi con il caricamento della pagina. Ho scoperto questo mettendo un po ‘di sleep(5) nel mio script lato server. Ho implementato la seguente soluzione basata sulla tua che sembra risolvere questo problema.

Fondamentalmente ho aggiunto un callback al tuo plugin jQuery per il preload, in modo che venga chiamato dopo che tutte le immagini sono state caricate correttamente.

 // 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() { $('').attr({ src: this }).load(function() { checklist.remove($(this).attr('src')); if (checklist.length == 0) { callback(); } }); }); }; 

Fuori di interesse, nel mio contesto, sto usando questo come segue:

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

Speriamo che questo aiuti qualcuno che viene in questa pagina da Google (come ho fatto io) a cercare una soluzione per il precaricamento delle immagini sulle chiamate Ajax.

Questo codice jQuery a una riga crea (e carica) un elemento DOM img senza mostrarlo:

 $(''); 
 $.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’utilizzo è abbastanza semplice:

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

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

Ho un piccolo plugin che gestisce questo.

Si chiama waitForImages e può gestire elementi img o qualsiasi elemento con un riferimento a un’immagine nel CSS, ad esempio div { background: url(img.png) } .

Se volevi semplicemente caricare tutte le immagini, incluse quelle a cui fai riferimento nel CSS, ecco come lo faresti 🙂

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

puoi caricare le immagini nel tuo html da qualche parte usando il display:none; css display:none; regola, quindi mostrali quando vuoi con js o jquery

non usare js o le funzioni jquery per il precaricamento è solo una regola css Vs molte righe di js da eseguire

esempio: HTML

  

Css:

 .hide{ display:none; } 

jQuery:

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

Il precaricamento delle immagini con jquery / javascript non va bene perché le immagini impiegano pochi millisecondi per caricare in pagina + hai millisecondi perché lo script sia analizzato ed eseguito, specialmente se sono immagini grandi, quindi nasconderle in hml è meglio anche per le prestazioni, perché l’immagine è davvero precaricata senza essere visibile a tutti, finché non lo mostri!

questo plugin jquery imageLoader è solo 1,39 kb

utilizzo:

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

ci sono anche altre opzioni come se vuoi caricare le immagini in modo sincrono o asincrono e un evento completo per ogni singola immagine.

Un modo rapido e privo di plug-in per precaricare le immagini in jQuery e ottenere una funzione di callback consiste nel creare più tag img contemporaneamente e contare le risposte, ad es.

 function preload(files, cb) { var len = files.length; $(files.map(function(f) { return ''; }).join('')).load(function () { if(--len===0) { cb(); } }); } preload(["one.jpg", "two.png", "three.png"], function() { /* Code here is called once all files are loaded. */ });​ ​ 

Nota che se vuoi supportare IE7, dovrai usare questa versione leggermente meno carina (che funziona anche con altri browser):

 function preload(files, cb) { var len = files.length; $($.map(files, function(f) { return ''; }).join('')).load(function () { if(--len===0) { cb(); } }); } 

Grazie per questo! Mi piacerebbe aggiungere un piccolo riff alla risposta di JP: non so se questo aiuterà qualcuno, ma in questo modo non devi creare una serie di immagini e puoi precaricare tutte le tue immagini grandi se nominare i pollici correttamente. Questo è utile perché ho qualcuno che sta scrivendo tutte le pagine in html, e garantisce un passo in meno da fare per loro – eliminando la necessità di creare l’array di immagini, e un altro passo in cui le cose potrebbero farsi rovinare.

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

Fondamentalmente, per ogni immagine sulla pagina afferra lo src di ogni immagine, se corrisponde a determinati criteri (è un pollice, o l’immagine della home page) cambia il nome (una stringa di base sostituisce nell’immagine src), quindi carica le immagini .

Nel mio caso la pagina era piena di immagini del pollice tutte denominate qualcosa come image_th.jpg e tutte le corrispondenti immagini di grandi dimensioni sono denominate image_lg.jpg. Il pollice al grande sostituisce semplicemente il _th.jpg con _lg.jpg e quindi precarica tutte le immagini di grandi dimensioni.

Spero che questo aiuti qualcuno.

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

Io uso il seguente codice:

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

Vorrei usare un file manifest per dire ai (moderni) browser web di caricare anche tutte le immagini rilevanti e memorizzarle nella cache. Usa Grunt e grunt-manifest per farlo automaticamente e non preoccuparti mai di script di precaricamento, invalidatori di cache, CDN ecc.

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

Questo funziona per me anche in IE9:

 $('').on('load', function(){ doOnLoadStuff(); }); 

Volevo farlo con una sovrapposizione personalizzata dell’API di Google Maps. Il loro codice di esempio utilizza semplicemente JS per inserire elementi IMG e la casella segnaposto immagine viene visualizzata fino a quando l’immagine non viene caricata. Ho trovato una risposta qui che ha funzionato per me: https://stackoverflow.com/a/10863680/2095698 .

 $('').load(function() { $(this).width(some).height(some).appendTo('#some_target'); }); 

Questo precarica un’immagine come suggerito prima e quindi usa il gestore per aggiungere l’object img dopo che l’URL img è stato caricato. La documentazione di jQuery avverte che le immagini memorizzate nella cache non funzionano bene con questo codice evento / gestore, ma funzionano per me in FireFox e Chrome e non devo preoccuparmi di IE.

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

.attr('src',value)

non

.attr('src',this)

solo per indicarlo 🙂

5 righe in 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 

Per coloro che conoscono un po ‘di actionscript, puoi verificare il flash player, con il minimo sforzo, e creare un preloader flash, che puoi anche esportare in html5 / Javascript / Jquery. Per utilizzare se il flash player non viene rilevato, controlla esempi su come farlo con il ruolo di youtube in html5 player 🙂 e creane uno tuo. Non ho i dettagli, perché non ho ancora iniziato, se non lo dimentico, lo posterò più tardi e proverò qualche codice Jquery standerd per il mio.

Tutti gli hipster hanno scritto lì la propria versione, quindi ecco la mia. Appende un div nascosto al corpo e lo riempie con le immagini richieste. L’ho scritto in Coffee Script. Ecco il caffè, il js normale e il js compresso.

Caffè:

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

Normale:

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

compressa:

 function(){$.fn.preload=function(){var a,b=this;return a=$("
").css("display","none"),$("body").append(a),this.each(function(b,c){return a.append($("").attr("src",c))})}}.call(this);