2011-12-30 79 views
5

我想要一個函數在加載特定圖像時運行,但我不知道如何在運行前等待兩者加載。我只知道如何把它們連,如下圖所示:我可以同步多個圖像onload呼叫嗎?

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

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

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

這樣做的缺點是它必須等待,直到獲得此搜索前一秒完全負載。我想嘗試這樣的事情:

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

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

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

編輯:謝謝你的幫助保羅格里姆和ziesemer。你的答案都非常好。我想我必須給Paul Grime最好的答案,雖然他使用了更多的代碼,但我只需要知道圖像的src,並且onload函數是內置的,而在ziesemer的答案中,我需要知道src,count的圖像,並且必須寫入多條onload行。

根據具體情況,兩者都有其目的。謝謝你們的幫助。

+0

你能用jQuery嗎? – 2011-12-30 17:20:50

+0

是的,jQuery可用 – 2011-12-30 18:23:02

回答

10

這撥弄可能的幫助。這是一個簡單的通用'裝載機'。

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

,代碼:

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

這是如何處理加載錯誤的? – Metropolis 2017-04-20 23:03:54

10

如果您不能使用的東西像jQuery,創建一個輔助函數,你可以傳遞給所有的圖像你有興趣,每一個被調用時的onload,增加一個計數器,或添加src名稱一套。一旦櫃檯或你的設置達到了你所期望的所有圖像的大小,那麼你可以開始你想做的任何工作。

喜歡的東西:

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

&如果你可以使用jQuery? – jedierikb 2013-05-10 16:56:08

1

我把保羅污穢物的上面的例子,並修改它更易理解,同時還實現了OP需要。我覺得這裏的其他答案要麼複雜,要麼不夠。希望這段代碼更容易拾取和放入。我爲每個循環使用了下劃線,但這很容易改變。

另外,我現在改進了解決方案,對img錯誤進行回調。如果圖像被加載,它會被添加到數組中,如果失敗則不會。我也改變它來利用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"]); 
    }); 
},