37

iframe を動的に作成したところ、この iframe が onload イベントを 2 回トリガーすることがわかりました。

var i=0;
frameOnload=function(){
  console.log(i++);  
};

var ifr=document.createElement("iframe");  
ifr.src="javascript:(function(){document.open();document.write('test');document.close();})();";
ifr.onload=frameOnload;  
document.body.appendChild(ifr);

なぜ私は最終的に 1 ですか?
onload 関数を内部で null にポイントする代わりに、iframe の onload を 2 回防止するにはどうすればよいですか?

4

8 に答える 8

66

私も同じ問題に遭遇しましたが、どこにも答えがないので、自分でテストしました。

iframe が本体に追加される前に onload イベントをアタッチすると、iframe onload イベントは Webkit ブラウザー ( safari/chrome ) で 2 回トリガーされます。

したがって、次の方法でコードを変更することで、iframe のオンロードを 2 回防ぐことができます。

document.body.appendChild(ifr);
ifr.onload=frameOnload; // attach onload event after the iframe is added to the body

次に、ドキュメントが実際にロードされたイベントである onload イベントを 1 つだけ取得します。

于 2013-04-08T13:33:40.497 に答える
23

最多投票の回答を拡張するには:いつ、どのように DOM に接続するかを制御できない場合(たとえば、フレームワークを使用している場合 (Angular アプリでこれが発生しました))、次のことが必要になる場合があります。以下の解決策を試してください。

クロスブラウザー テストを行ったところ、次の回避策が見つかりました。コールバックに渡されたパラメーターを確認し、イベント リスナーで検査します。onloadevt.target.src

iframe.onload = function(evt) {
    if (evt.target.src != '') {
        // do stuff
    }
}

(HTML からグローバル メソッドを呼び出す場合eventは、HTML マークアップを渡すことを忘れないでください: <iframe onload="window.globalOnLoad(event)">)

evt.target.src私のテストから、''最初の呼び出しで webkit でのみ (空の文字列)にすることができます。onload

さまざまな状況での iframe のオンロード動作の研究

iframe.onload = function(evt){
    console.log("frameOnload", ++i);
    console.log("src = '" + evt.target.src + "'");
};

通常の URL での iframe のオンロード動作

// Chrome:  onload 1 src='', onload 2 src=requestedSrc
// IE11:    onload 1 src=requestedSrc
// Firefox: onload 1 src=requestedSrc
document.body.appendChild(iframe);
iframe.src = "http://www.example.org/";

404 URL での iframe オンロード動作

// Chrome:  onload 1 src='', onload 2 src=requestedSrc
// IE11:    onload 1 src=requestedSrc
// Firefox: onload 1 src=requestedSrc
document.body.appendChild(iframe);
iframe.src = "http://www.example.org/404";

(DNS レベルで) 解決できない URL での iframe オンロード動作

// Chrome:  onload 1 src='', onload 2 src=requestedSrc
// IE11:    onload 1 src=requestedSrc
// Firefox: onload NEVER triggered!
document.body.appendChild(iframe);
iframe.src= 'http://aaaaaaaaaaaaaaaaaaaaaa.example/';

DOM に追加する前にiframe.src明示的に設定されたiframe のオンロード動作about:blank

// Chrome:  onload 1 src='about:blank', onload 2 src=requestedSrc
// IE11:    onload 1 src=requestedSrc
// Firefox: onload 1 src=requestedSrc
iframe.src = "about:blank";
document.body.appendChild(iframe);
iframe.src = "http://www.example.org/";

iframe.srcDOM に追加する前に明示的に JavaScript 式に設定されたiframe のオンロード動作

// Chrome:  onload 1 src='javascript:void 0', onload 2 src=requestedSrc
// IE11:    onload 1 src=requestedSrc
// Firefox: onload 1 src=requestedSrc
iframe.src = "javascript:void 0";
document.body.appendChild(iframe);
iframe.src = "http://www.example.org/";
于 2016-07-19T13:10:58.800 に答える
0

FWIW、onloadの場合は二重にiframe.src再現javascript:できましたが、通常の HTTP URL では再現できませんでした (onload は 1 回発生していました)。ただし、iframe.srcボディに追加した後に設定されるように呼び出しの順序を変更すると、二重ロードが発生します (これも Webkit のみ)。

var i = 0;

var iframe = document.createElement("iframe");
iframe.onload = function(){
  console.log("frameOnload", ++i);
};
document.body.appendChild(iframe);
iframe.src = "http://www.example.org/";
//iframe.src = "http://www.example.org/404";

// double onload!

を追加する前割り当てるsrcと、1回のonload呼び出しが発生します。

var i = 0;

var iframe = document.createElement("iframe");
iframe.onload = function(){
  console.log("frameOnload", ++i);
};
iframe.src = "http://www.example.org/";
//iframe.src = "http://www.example.org/404";
document.body.appendChild(iframe);

// only one onload
于 2016-07-19T08:34:23.433 に答える
0

ここでうまくいくコード!

クレジット: @Dave Stolie https://coderanch.com/t/443223/languages/Frames-loading-refresh

<html>  
 <head>  
   <script type="text/javascript">  
     function loadFrame()  
     {
        var url="http://www.google.com";
        alert(document.getElementById("theFrame").src);

        if (document.getElementById("theFrame").src != url)
        {
            alert("loading");
            document.getElementById("theFrame").src = url;  
        }
     }  
   </script>  
   </head>  
   <body onLoad="loadFrame();">  
   <iframe id="theFrame" src="x"/>
  </body>  
  </html>
于 2019-06-19T08:02:18.560 に答える
0

vue.js 2.6.12 でこの問題に直面しました。iframe
の onload 関数内で event.target.url が src url と一致するかどうかを確認して処理しました。

<template>
           <iframe
                @load="onLoad"
                :src="embedUrl"
                ref="cardNumber"
                frameborder="0"
                scrolling="no"
                width="100%"
                height="100%"
                align="left"
            ></iframe>
</template>


<script>
export default {
...,
methods: {
onLoad (event) {
    // considerting iframe to be loaded if the event.target.url matches the src url
    if(event.target.src === this.embedUrl)) {
      // instructions after loading
    } 
   }
 }
}
</script>
于 2021-02-26T12:47:45.343 に答える