动态创建的iframe触发onload事件两次(dynamically created iframe

2019-06-24 21:28发布

我创建了一个iframe动态,发现这个iframe的触发onload事件两次。

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?
如何防止iframe的onload事件,而不是两次指向的onload功能空里面本身?

Answer 1:

我也遇到同样的问题,但没有得到答案的任何地方,所以我测试由我自己。

iframe的onload事件将在两次WebKit浏览器(Safari /铬)被触发,如果附加在onload事件之前的iframe追加到身体。

这样就可以防止iframe的onload事件通过两次更改以下列方式你的代码。

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

然后,你只会得到一个onload事件,这是真正的文件加载事件。



Answer 2:

为了扩大对得票最多的回答是: 如果在和事情是如何连接到DOM你无法控制-例如,使用框架的时候 (我们已经有这种事情发生在我们的角应用程序) - 您可能希望请尝试以下解决方案。

我做了沉重的跨浏览器测试,我发现了以下解决方法: 检查传递给该参数onload回调,检查evt.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的onload行为

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

与普通URL的iframe的onload行为

// 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网址的iframe的onload行为

// 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的onload行为

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

关于iframe的onload行为iframe.src明确设置为about:blank附加到DOM之前

// 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的onload行为iframe.src明确设置为一个JavaScript表达式附加到DOM之前

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


Answer 3:

FWIW,而我是能够重现双onload的情况下iframe.srcjavascript:我无法用正常的HTTP URL复制它(onload事件是发生一次)。 但是,当你改变调用的顺序,使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追加之前 ,我得到一个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


Answer 4:

我有这种事发生在异步加载样式表,像这样的。

<link rel="preload" href="stylesheet.css" as="style" onload="this.rel='stylesheet'">

我发现,最简单的办法是让事件本身删除:

<link rel="preload" href="stylesheet.css" as="style" onload="this.removeAttribute('onload'); this.rel='stylesheet'">


文章来源: dynamically created iframe triggers onload event twice