Precarga de Imágenes de JavaScript


¿Puede decirme si la función que escribí a continuación es suficiente para precargar imágenes en la mayoría, si no en todos los navegadores comúnmente utilizados hoy en día?

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

Tengo una matriz de imageURLs que hago un bucle y llamo a la función preloadImage para cada URL.

Author: Alexis Wilke, 2010-09-05

8 answers

Sí. Esto debería funcionar en todos los navegadores principales.

 94
Author: Huzi--- Javiator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-16 19:01:18

Prueba esto Creo que esto es mejor.

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://domain.tld/gallery/image-001.jpg",
    "http://domain.tld/gallery/image-002.jpg",
    "http://domain.tld/gallery/image-003.jpg"
)

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

 36
Author: clintgh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-14 02:56:10

CSS2 Alternativa: 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; 
}

CSS3 Alternativa: 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: Es posible que las imágenes en un contenedor con display:none no se carguen previamente. Tal vez la visibilidad: oculto funcionará mejor, pero no he probado esto. Gracias Marco Del Valle por señalar esto

 20
Author: mplungjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-18 05:30:30

Te recomiendo que uses un try / catch para evitar algunos posibles problemas:

OOP:

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

Estándar:

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

Además, aunque me encanta DOM, los viejos navegadores estúpidos pueden tener problemas con usted usando DOM, así que evítelo por completo en MI humilde opinión, contrariamente a la contribución de freedev. Image () tiene mejor soporte en navegadores de basura antiguos.

 10
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-12 21:00:58

Este enfoque es un poco más elaborado. Aquí se almacenan todas las imágenes precargadas en un contenedor, puede ser un div. Y después podría mostrar las imágenes o moverlo dentro del DOM a la posición correcta.

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

Pruébalo aquí, también he añadido algunos comentarios

 9
Author: freedev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-24 00:18:52

En mi caso, fue útil agregar una devolución de llamada a su función para el evento onload:

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

Y luego envuélvalo para el caso de una matriz de url a imágenes que se precargarán con devolución de llamada en todo está hecho: 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');
});
 9
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-05 22:04:51

Sí, esto funcionará, sin embargo los navegadores limitarán (entre 4-8) las llamadas reales y, por lo tanto, no almacenarán en caché/precargarán todas las imágenes deseadas.

Una mejor manera de hacer esto es llamar a onload antes de usar la imagen de esta manera:

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;
}
 3
Author: Robin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-12 21:31:01

Aquí está mi enfoque:

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);
    }
};
 2
Author: naeluh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-15 18:24:17