2011-12-30 7 views
5

Quiero que se ejecute una función cuando se cargan imágenes específicas, pero no sé cómo esperar a que ambas se carguen antes de ejecutarse. Sólo sé cómo ellas cadena, como a continuación:¿Puedo sincronizar varias llamadas de carga de imagen?

Image1 = new Image(); 
Image1.src = 'image1-link.jpg'; 

Image2 = new Image(); 
Image2.src = 'image2-link.jpg'; 

Image1.onload = function() { 
    Image2.onload = function() { ... } 
} 

La desventaja de esto es que tiene que esperar hasta Image1 totalmente cargado antes de conseguir el segundo. Quiero intentar algo como esto:

Image1 = new Image(); 
Image1.src = 'image1-link.jpg'; 

Image2 = new Image(); 
Image2.src = 'image2-link.jpg'; 

(Image1 && Image2).onload = function() { ... } 

EDIT: gracias a ambos por la ayuda de Paul Grime y Ziesemer. Ambas tus respuestas son muy buenas. Creo que tengo que dar la mejor respuesta a Paul Grime, aunque usa más código, solo necesito saber el código de las imágenes y la función de carga está incorporada mientras que en la respuesta de ziesemer necesito saber tanto el src como el conteo. de las imágenes, y tiene que escribir múltiples líneas de carga.

Dependiendo de la situación, ambos tienen su propósito. Gracias a ambos por la ayuda.

+0

¿Se puede usar jquery? –

+0

Sí, jQuery está disponible –

Respuesta

10

Esto podría ayudar violín. Es un simple 'cargador' genérico.

http://jsfiddle.net/8baGb/1/

Y el código:

// loader will 'load' items by calling thingToDo for each item, 
// before calling allDone when all the things to do have been done. 
function loader(items, thingToDo, allDone) { 
    if (!items) { 
     // nothing to do. 
     return; 
    } 

    if ("undefined" === items.length) { 
     // convert single item to array. 
     items = [items]; 
    } 

    var count = items.length; 

    // this callback counts down the things to do. 
    var thingToDoCompleted = function (items, i) { 
     count--; 
     if (0 == count) { 
      allDone(items); 
     } 
    }; 

    for (var i = 0; i < items.length; i++) { 
     // 'do' each thing, and await callback. 
     thingToDo(items, i, thingToDoCompleted); 
    } 
} 

function loadImage(items, i, onComplete) { 
    var onLoad = function (e) { 
     e.target.removeEventListener("load", onLoad); 

     // this next line can be removed. 
     // only here to prove the image was loaded. 
     document.body.appendChild(e.target); 

     // notify that we're done. 
     onComplete(items, i); 
    } 
    var img = new Image(); 
    img.addEventListener("load", onLoad, false); 
    img.src = items[i]; 
} 

var items = ['http://bits.wikimedia.org/images/wikimedia-button.png', 
      'http://bits.wikimedia.org/skins-1.18/common/images/poweredby_mediawiki_88x31.png', 
      'http://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png', 
      'http://upload.wikimedia.org/wikipedia/commons/3/38/Icons_example.png']; 

loader(items, loadImage, function() { 
    alert("done"); 
}); 
+0

¿Cómo maneja esto los errores de carga? – Metropolis

10

Si no puede usar algo como jQuery, cree una función de ayuda que pueda pasar al onload de todas sus imágenes que le interesan. Cada vez que se invoca, incremente un contador o agregue el nombre src para un conjunto. Una vez que el contador o su conjunto alcanza el tamaño de todas las imágenes que está esperando, puede despedir cualquier trabajo que realmente desee hacer.

Algo así como:

var imageCollector = function(expectedCount, completeFn){ 
    var receivedCount; 
    return function(){ 
    if(++receivedCount == expectedcount){ 
     completeFn(); 
    } 
    }; 
}(); 

var ic = imageCollector(2, function(){alert("Done!");}); 
Image1.onload = ic; 
Image2.onload = ic; 
+2

y si puede usar jQuery? – jedierikb

1

Me tomó el ejemplo de Pablo Grime arriba y modificado para hacerlo más comprensible al mismo tiempo el cumplimiento de la necesidad OP. Sentí que las otras respuestas aquí eran complicadas o insuficientes. Espero que este código sea un poco más fácil de recoger y poner. Usé un guión bajo para cada ciclo, pero esto es fácil de cambiar.

Además, mejoré la solución ahora para tener una devolución de llamada para el error img. Si la imagen está cargada, se agrega a la matriz, si falla no lo es. También lo cambié para utilizar jquery.

var loadedImages = [], 
    imagePaths = [{"src": "myimg.png"}, {"src": "myotherimg.png"}]; 

loadImages(imagePaths, loadedImages, function(loadedImages) { 
    console.log(loadedImages) 
}); 

function loadImages(imagePaths, loadedImages, callback) { 
    if (!imagePaths) { return; } 

    var count = imagePaths.length; 

    _.each(imagePaths, function(data, key, list) { 
     var onLoad = function (e) { 
      count--; 
      if (0 == count) { 
       callback(loadedImages); 
      } 
     } 

     $(document.createElement("img")) 
      .on('load', function() { 
       loadedImages.push(data); 
       onLoad(); 
      }) 
      .on('error', function() { onLoad(); }) 
      .attr("src", data["src"]); 
    }); 
}, 
Cuestiones relacionadas