2012-06-17 58 views
6

Después de leer las preguntas de otras personas que penséJavascript - ejecutar después de que todas las imágenes han cargado

window.onload=... 

podría responder a mi pregunta. Lo he intentado pero ejecuta el código en el instante en que la página se carga (no después de cargar las imágenes).

Si hace alguna diferencia, las imágenes provienen de un CDN y no son relativas.

¿Alguien sabe una solución? (No estoy usando jQuery)

+1

Publique su código. –

+1

¿Qué quieres lograr? Tal vez haya algo más eficiente que precargar imágenes. – Alp

Respuesta

16

Aquí es un truco rápido para navegadores modernos: "Todas las imágenes cargadas"

var imgs = document.images, 
    len = imgs.length, 
    counter = 0; 

[].forEach.call(imgs, function(img) { 
    img.addEventListener('load', incrementCounter, false); 
}); 

function incrementCounter() { 
    counter++; 
    if (counter === len) { 
     console.log('All images loaded!'); 
    } 
} 

Una vez que todas las imágenes se cargan, la consola mostrará.

Lo que hace este código:

  • cargar todas las imágenes en una variable a partir del documento
  • bucle a través de estas imágenes
  • Añadir un detector para el evento "carga" en cada una de estas imágenes para ejecutar la función incrementCounter
  • el incrementCounter va a incrementar el contador
  • Si el contador ha alcanzado la longitud de las imágenes, que significa que son todos cargados

Tener este código de una manera multi-navegador no sería tan dura, es sólo más limpio como este.

+1

Dos notas: si la secuencia de comandos se carga tarde, es posible que se pierda algunos eventos que causan que la secuencia de comandos nunca se complete. Además, es posible que su navegador no cargue todas las imágenes que inicialmente están ocultas por css. – Micros

2

El uso de window.onload no funciona porque se dispara una vez que se carga la página, sin embargo, las imágenes no se incluyen en esta definición de cargado.

La solución general a esto es el plugin jQuery ImagesLoaded.

Si le interesa no usar jQuery en absoluto, al menos intente convertir este complemento en Javascript puro. En 93 líneas importantes de código y con buenos comentarios, no debería ser una tarea difícil de lograr.

1

Puede tener el evento de carga en la imagen que puede devolver una función que procesa ... Con respecto a cómo manejar si se cargan todas las imágenes, no estoy seguro de que alguno de los siguientes mecanismos funcione:

tienen una función que cuenta el número de imágenes para las que se llama a la carga, si esto es igual al número total de imágenes en su página, entonces haga su procesamiento necesario.

0

Estaba a punto de sugerir lo mismo que dijo Baz1nga.

Además, otra opción posible que quizás no sea tan infalible pero sea más fácil de mantener es elegir la imagen más importante/más grande y adjuntar un evento de carga a solo esa. la ventaja aquí es que hay menos código para cambiar si luego agrega más imágenes a su página.

1
<title>Pre Loading...</title> 
</head> 

<style type="text/css" media="screen"> html, body{ margin:0; 
padding:0; overflow:auto; } 
#loading{ position:fixed; width:100%; height:100%; position:absolute; z-index:1; ackground:white url(loader.gif) no-repeat center; }** 
</style> 

<script> function loaded(){ 
document.getElementById("loading").style.visibility = "hidden"; } 
</script> 

<body onload="loaded();"> <div id="loading"></div> 

<img id="img" src="avatar8.jpg" title="AVATAR" alt="Picture of Avatar 
movie" /> 


</body> 
6

Promise Pattern resolverá este problema de la mejor manera posible me he referido a cuándo.js una biblioteca de código abierto para resolver el problema de toda la carga de imágenes

function loadImage (src) { 
    var deferred = when.defer(), 
     img = document.createElement('img'); 
    img.onload = function() { 
     deferred.resolve(img); 
    }; 
    img.onerror = function() { 
     deferred.reject(new Error('Image not found: ' + src)); 
    }; 
    img.src = src; 

    // Return only the promise, so that the caller cannot 
    // resolve, reject, or otherwise muck with the original deferred. 
    return deferred.promise; 
} 

function loadImages(srcs) { 
    // srcs = array of image src urls 

    // Array to hold deferred for each image being loaded 
    var deferreds = []; 

    // Call loadImage for each src, and push the returned deferred 
    // onto the deferreds array 
    for(var i = 0, len = srcs.length; i < len; i++) { 
     deferreds.push(loadImage(srcs[i])); 

     // NOTE: We could push only the promise, but since this array never 
     // leaves the loadImages function, it's ok to push the whole 
     // deferred. No one can gain access to them. 
     // However, if this array were exposed (e.g. via return value), 
     // it would be better to push only the promise. 
    } 

    // Return a new promise that will resolve only when all the 
    // promises in deferreds have resolved. 
    // NOTE: when.all returns only a promise, not a deferred, so 
    // this is safe to expose to the caller. 
    return when.all(deferreds); 
} 

loadImages(imageSrcArray).then(
    function gotEm(imageArray) { 
     doFancyStuffWithImages(imageArray); 
     return imageArray.length; 
    }, 
    function doh(err) { 
     handleError(err); 
    } 
).then(
    function shout (count) { 
     // This will happen after gotEm() and count is the value 
     // returned by gotEm() 
     alert('see my new ' + count + ' images?'); 
    } 
); 
+0

Esta debería ser la respuesta aceptada. Solución moderna, funciona genial Kudos Ajay – TaylorMac

0

Un poco tarde al juego, pero he encontrado el siguiente método que es el más sencillo:

function waitForImages() { 
    let isLoading = true 

    while (isLoading) { 
    const loading = [].slice.call(document.images).filter(img => img.complete !== true) 
    if (!loading.length > 0) { 
     isLoading = true 
     return 
    } 
    } 
} 

Tenga en cuenta que esto es código de bloqueo (es útil si intenta asegurarse de que las imágenes se carguen en algo como phantomjs)

Cuestiones relacionadas