背景
複数の iframe をページ内に配置して、各々の iframe のコンテンツをごにょごにょする場合、 全ての iframe の読み込み( load )が終わるのを待ってから処理を行わないとタイミングによって、 iframe の DOM を JavaScript でつかめたり、つかめなかったりして動作が安定しません。
jQuery の Deffered を使って全ての iframe の読み込みを待つことで、この問題をクリアできます。
コード
HTML
<div id="mainContents">
<div id="frameAContainer">
</div>
<div id="frameBContainer">
</div>
<div id="frameCContainer">
</div>
</div>
JavaScript
共通関数
function iFrameLoaded(id, src) {
var deferred = $.Deferred(),
iframe = $("<iframe></iframe>").attr({
"id": id,
"src": src
});
iframe.on('load', deferred.resolve);
iframe.appendTo("#" + id + "Container");
deferred.done(function() {
console.log("iframe loaded: " + id);
});
return deferred.promise();
}
main
$(function() {
$.when(iFrameLoaded("frameA", "./framea.html"), iFrameLoaded("frameB", "./frameb.html"), iFrameLoaded("frameC", "./framec.html")).then(function() {
console.log("All iframes loaded");
// OK, Ready! Do Something!!
});
});
少しだけ解説
iframe を 最初から HTML 上に配置するのではなく、 iframe を格納するコンテナ( frameAContainer
〜 frameCContainer )だけ用意しておき、 iframe は JavaScript で動的に生成して load を待つように Deffered でセットしています。 最初から HTML 上に配置する方法では私の環境( MacOSX )では、load をつかめない場合がありました。
このコードは MacOSX の環境で Safari 、 FireFox 、 Chrome で動作確認済です。
参考サイト
jQuery.Deferred to Tell When Certain iframes Are Loaded · Elijah Manor