2011-12-30 7 views
5

特定のイメージがロードされたときに関数を実行したいが、実行する前に両方のロードを待つ方法がわからない。私は以下のように、それらをチェーンする方法を知っている:複数のイメージオンロードコールを同期することはできますか?

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

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

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

この方法の欠点は、それは画像1が完全に第二を取得する前にロードするまで待たなければならないです。

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

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

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

EDIT:ヘルプポール・グライムとziesemerのためにあなたの両方をありがとう、私はこのような何かを試してみたいです。両方の答えはとても良いです。私はPaul Grimeに最善の答えを与えなければならないと思うが、彼はもっとコードを使っているが、画像のsrcを知る必要があるだけで、onload関数が組み込まれている.ziesemerの答えではsrc、複数のオンロードラインを書き込む必要があります。

状況によっては、どちらも目的があります。両方とも助けてくれてありがとう。

+0

jqueryを使用できますか? –

+0

はい、jQueryは利用可能です –

答えて

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

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

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"]); 
    }); 
}, 
関連する問題