2011-12-30 11 views
5

Desidero eseguire una funzione quando vengono caricate immagini specifiche, ma non so come aspettare che entrambe vengano caricate prima dell'esecuzione. Io so solo come loro catena, come di seguito:Posso sincronizzare più chiamate onload di immagini?

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

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

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

L'aspetto negativo di questo è che ha aspettare fino Image1 completamente caricata prima di ottenere il secondo. Voglio provare qualcosa di simile:

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

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

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

EDIT: Vi ringrazio entrambi per l'aiuto Paul Grime e Ziesemer. Entrambe le tue risposte sono molto buone. Penso di dover dare la migliore risposta a Paul Grime, sebbene usi più codice, ho solo bisogno di conoscere l'src delle immagini e la funzione onload è integrata mentre nella risposta di ziesemer ho bisogno di conoscere sia l'src, il conteggio delle immagini e devono scrivere più linee di carico.

A seconda della situazione, entrambi hanno il loro scopo. Grazie a entrambi per l'aiuto.

+0

è possibile utilizzare jquery? –

+0

Sì, jQuery è disponibile –

risposta

10

Questo violino potrebbe aiutare. È un semplice "caricatore" generico.

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

E il codice:

// 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

In che modo si tratta di errori di caricamento? – Metropolis

10

Se non si può usare qualcosa come jQuery, creare una funzione di supporto che è possibile passare alla onload di tutte le immagini che vi interessano. Ogni volta che viene chiamato, incrementare un contatore, o aggiungere il nome src a un set. Una volta che il contatore o il tuo set raggiunge la dimensione di tutte le immagini che ti aspetti, puoi licenziare qualsiasi lavoro tu voglia veramente fare.

Qualcosa di simile:

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

e se è possibile utilizzare jQuery? – jedierikb

1

ho preso l'esempio di Paolo Grime sopra e modificato per essere più comprensibile, pur realizzando la necessità OP. Ho sentito che le altre risposte qui erano o complicate o non abbastanza. Speriamo che questo codice sia un po 'più facile da raccogliere e inserire. Ho usato il trattino basso per ogni ciclo, ma questo è facile da cambiare.

Inoltre, ho migliorato la soluzione ora per avere un callback per errore img. Se l'immagine è caricata, viene aggiunta all'array, se fallisce non lo è. Ho anche cambiato per utilizzare 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"]); 
    }); 
}, 
Problemi correlati