Pré-carregando imagens com jQuery

Estou procurando uma maneira rápida e fácil de pré-carregar imagens com JavaScript. Estou usando o jQuery se isso for importante.

Eu vi isso aqui ( 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" }); } }; 

Mas, parece um pouco over-the-top para o que eu quero!

Eu sei que existem plugins jQuery lá fora que fazem isso, mas todos eles parecem um pouco grandes (em tamanho); Eu só preciso de uma maneira rápida, fácil e rápida de pré-carregar imagens!

Rápido e fácil:

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

Ou, se você quiser um plugin jQuery:

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

Aqui está uma versão ajustada da primeira resposta que realmente carrega as imagens no DOM e as oculta por padrão.

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

Use o object JavaScript Image .

Esta function permite que você acione um retorno de chamada ao carregar todas as imagens. No entanto, observe que ele nunca acionará um retorno de chamada se pelo menos um recurso não for carregado. Isso pode ser facilmente corrigido implementando o retorno de chamada do onerror e incrementando o valor loaded ou manipulando o erro.

 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, Depois de verificar sua solução, eu ainda estava tendo problemas no Firefox, onde não pré-carregava as imagens antes de ir carregando a página. Eu descobri isso colocando um pouco de sleep(5) no meu script do lado do servidor. Eu implementei a seguinte solução baseada na sua que parece resolver isso.

Basicamente eu adicionei um retorno de chamada ao seu plugin de pré-carregamento do jQuery, para que ele seja chamado depois que todas as imagens forem carregadas corretamente.

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

Fora de interesse, no meu contexto, estou usando isso da seguinte maneira:

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

Espero que isso ajude alguém que chega a esta página do Google (como eu) à procura de uma solução para o pré-carregamento de imagens em chamadas Ajax.

Esta linha de código jQuery cria (e carrega) um elemento DOM img sem mostrá-lo:

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

O uso é bem simples:

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

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

Eu tenho um pequeno plugin que lida com isso.

É chamado waitForImages e pode manipular elementos img ou qualquer elemento com uma referência a uma imagem no CSS, por exemplo, div { background: url(img.png) } .

Se você simplesmente quisesse carregar todas as imagens, incluindo aquelas referenciadas no CSS, veja como você faria isso 🙂

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

você pode carregar imagens no seu html em algum lugar usando css display:none; regra, então mostre-os quando quiser com js ou jquery

não use funções js ou jquery para pré-carregar é apenas uma regra css Vs muitas linhas de js a serem executadas

exemplo: Html

  

Css:

 .hide{ display:none; } 

jQuery:

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

O pré-carregamento de imagens por jquery / javascript não é bom porque as imagens demoram alguns milissegundos para serem carregadas na página + você tem milissegundos para o script ser analisado e executado, especialmente se forem imagens grandes, então ocultá-los em hml é melhor também para desempenho porque a imagem é realmente pré-carregada sem ser visível, até que você mostre isso!

este plugin jquery imageLoader é apenas 1.39kb

uso:

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

Há também outras opções, como se você deseja carregar as imagens de forma síncrona ou assíncrona e um evento completo para cada imagem individual.

Uma maneira rápida e livre de plug-ins para pré-carregar imagens no jQuery e obter uma function de retorno de chamada é criar várias tags img uma só vez e contar as respostas, por exemplo

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

Note que se você quiser dar suporte ao IE7, você precisará usar essa versão um pouco menos bonita (que também funciona em outros navegadores):

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

Obrigado por isso! Eu gostaria de acrescentar um pequeno riff na resposta do JP – eu não sei se isso vai ajudar alguém, mas desta forma você não precisa criar uma série de imagens, e você pode pré-carregar todas as suas imagens grandes se você nomeie seus polegares corretamente. Isso é útil porque eu tenho alguém que está escrevendo todas as páginas em html, e isso garante um passo a menos para elas – eliminando a necessidade de criar o array de imagens, e outro passo em que as coisas podem se estragar.

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

Basicamente, para cada imagem na página ela pega o src de cada imagem, se ela corresponde a certos critérios (é um thumb, ou imagem de home page) ela muda o nome (uma string básica substitui na imagem src), então carrega as imagens .

No meu caso, a página estava cheia de imagens de polegar, todas com o nome image_th.jpg, e todas as imagens grandes correspondentes são nomeadas image_lg.jpg. O polegar para grandes apenas substitui o _th.jpg por _lg.jpg e, em seguida, pré-carrega todas as imagens grandes.

Espero que isso ajude alguém.

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

Eu uso o seguinte código:

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

Eu usaria um arquivo de manifesto para dizer (moderno) navegadores para carregar também todas as imagens relevantes e armazená-los em cache. Use Grunt e grunt-manifest para fazer isso automaticamente e nunca mais se preocupe com scripts de pré-carregamento, invalidadores de cache, CDN etc.

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

Isso funciona para mim mesmo no IE9:

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

Eu queria fazer isso com uma sobreposição personalizada da API do Google Maps. Seu código de amostra simplesmente usa JS para inserir elementos IMG e a checkbox de espaço reservado para imagem é exibida até que a imagem seja carregada. Eu encontrei uma resposta aqui que funcionou para mim: https://stackoverflow.com/a/10863680/2095698 .

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

Isso pré-carrega uma imagem como sugerido anteriormente e, em seguida, usa o manipulador para append o object img após o URL img ser carregado. A documentação do jQuery avisa que as imagens em cache não funcionam bem com esse código de eventing / handler, mas está funcionando para mim no FireFox e no Chrome, e eu não preciso me preocupar com o IE.

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

.attr('src',value)

não

.attr('src',this)

apenas para apontar 🙂

5 linhas em 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 

Para aqueles que conhecem um pouco do actionscript, você pode verificar o flash player, com o mínimo de esforço, e criar um preloader de flash, que também pode exportar para html5 / Javascript / Jquery. Para usar se o flash player não for detectado, verifique exemplos de como fazer isso com o papel do youtube de volta para o html5 player 🙂 E crie o seu próprio. Eu não tenho os detalhes, porque eu ainda não comecei, se eu não esquecer, eu postá-lo mais tarde e vai experimentar algum código Jquery standerd para o meu.

Todos os hipsters escreveram sua própria versão, então aqui está a minha. Ele acrescenta um div oculto ao corpo e o preenche com as imagens necessárias. Eu escrevi no Coffee Script. Aqui está o Café, o js normal e o js comprimido.

Café:

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

Normal:

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

Comprimido:

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