Pré-carregar imagens do JavaScript

Você pode me dizer se a function que escrevi abaixo é suficiente para pré-carregar imagens na maioria, senão em todos os navegadores comumente usados ​​hoje em dia?

function preloadImage(url) { var img=new Image(); img.src=url; } 

Eu tenho uma matriz de imageURLs que eu loop e chamo a function preloadImage para cada URL.

Sim. Isso deve funcionar em todos os principais navegadores.

Tente isso, eu acho que isso é melhor.

 var images = []; function preload() { for (var i = 0; i < arguments.length; i++) { images[i] = new Image(); images[i].src = preload.arguments[i]; } } //-- usage --// preload( "http://sofpt.miximages.com/confirmation/image-001.jpg", "http://sofpt.miximages.com/confirmation/image-002.jpg", "http://sofpt.miximages.com/confirmation/image-003.jpg" ) 

Fonte: http://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Alternativa CSS2: http://www.thecssninja.com/css/even-better-image-preloading-with-css2

 body:after { content: url(img01.jpg) url(img02.jpg) url(img03.jpg); display: none; } 

Alternativa CSS3: https://perishablepress.com/preload-images-css3/ (H / T Linh Dam)

 .preload-images { display: none; width: 0; height: 0; background: url(img01.jpg), url(img02.jpg), url(img03.jpg); } 

NOTA: Imagens em um contêiner com display:none pode não ser pré-carregada. Talvez visibilidade: oculto funcionará melhor, mas eu não testei isso. Obrigado Marco Del Valle por apontar isso

Eu recomendo que você use um try / catch para evitar alguns possíveis problemas:

OOP:

  var preloadImage = function (url) { try { var _img = new Image(); _img.src = url; } catch (e) { } } 

Padrão:

  function preloadImage (url) { try { var _img = new Image(); _img.src = url; } catch (e) { } } 

Além disso, embora eu adore o DOM, navegadores antigos e estúpidos podem ter problemas com você usando o DOM, então evite-o completamente IMHO contrário à contribuição do freedev. Image () tem melhor suporte em navegadores de lixo antigos.

Essa abordagem é um pouco mais elaborada. Aqui você armazena todas as imagens pré-carregadas em um contêiner, pode ser um div. E depois você poderia mostrar as imagens ou movê-lo dentro do DOM para a posição correta.

 function preloadImg(containerId, imgUrl, imageId) { var i = document.createElement('img'); // or new Image() i.id = imageId; i.onload = function() { var container = document.getElementById(containerId); container.appendChild(this); }; i.src = imgUrl; } 

Experimente aqui , também adicionei alguns comentários

No meu caso, foi útil adicionar um retorno de chamada à sua function para o evento onload:

 function preloadImage(url, callback) { var img=new Image(); img.src=url; img.onload = callback; } 

E, em seguida, envolvê-lo para o caso de uma matriz de URLs para imagens a serem pré-carregadas com retorno de chamada em tudo é feito: https://jsfiddle.net/4r0Luoy7/

 function preloadImages(urls, allImagesLoadedCallback){ var loadedCounter = 0; var toBeLoadedNumber = urls.length; urls.forEach(function(url){ preloadImage(url, function(){ loadedCounter++; console.log('Number of loaded images: ' + loadedCounter); if(loadedCounter == toBeLoadedNumber){ allImagesLoadedCallback(); } }); }); function preloadImage(url, anImageLoadedCallback){ var img = new Image(); img.src = url; img.onload = anImageLoadedCallback; } } // Let's call it: preloadImages([ '//upload.wikimedia.org/wikipedia/commons/d/da/Internet2.jpg', '//www.csee.umbc.edu/wp-content/uploads/2011/08/www.jpg' ], function(){ console.log('All images were loaded'); }); 

Sim, isso funcionará, no entanto , os navegadores limitarão (entre 4 a 8) as chamadas reais e, portanto, não armazenarão em cache / pré-carregarão todas as imagens desejadas.

Uma maneira melhor de fazer isso é chamar onload antes de usar a imagem da seguinte forma:

 function (imageUrls, index) { var img = new Image(); img.onload = function () { console.log('isCached: ' + isCached(imageUrls[index])); *DoSomething..* img.src = imageUrls[index] } function isCached(imgUrl) { var img = new Image(); img.src = imgUrl; return img.complete || (img .width + img .height) > 0; } 

Aqui está minha abordagem:

 var preloadImages = function (srcs, imgs, callback) { var img; var remaining = srcs.length; for (var i = 0; i < srcs.length; i++) { img = new Image; img.onload = function () { --remaining; if (remaining <= 0) { callback(); } }; img.src = srcs[i]; imgs.push(img); } };