Firefox没有为动态嵌套iframe触发onload

时间:2015-11-04 22:55:27

标签: javascript html iframe

我有以下代码适用于Chrome和MS Edge但不适用于Firefox。

Parent.html有这个脚本。

<html>
<body>
<script>
var ifr1 = document.createElement('iframe');

ifr1.onload = function() {
    alert("iframe 1 loaded") //fires on all browsers
    script = ifr1.contentWindow.document.createElement('script');
    script.src = 'PATH/TO/script.js';
    script.onload = function() {
        alert("script 1 onload") //fires on all browsers
    };
    ifr1.contentWindow.document.body.appendChild(script);
};
document.body.appendChild(ifr1);

</script>
</body>
</html>

它会创建一个iframe,并在该iframe中加载script.js。

这是script.js,其功能与上面相同 -

var ifr2 = document.createElement('iframe');

ifr2.onload = function() {
    alert("iframe 2 loaded") //doesn't fire on Firefox
    script = ifr2.contentWindow.document.createElement('script');
    script.src = 'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js';
    script.onload = function() {
        alert("script 2 onload")
    };
    ifr2.contentWindow.document.body.appendChild(script);
};
document.body.appendChild(ifr2);

它会在Parent.html创建的iframe ifr2中创建另一个iframe ifr1

现在,Chrome和Edge会正确显示所有警报,但Firefox并没有触发ifr2内加载ifr1的onload事件(即使IE触发了ifr2的onload) 。知道为什么吗?

3 个答案:

答案 0 :(得分:1)

解决方法是创建一个简单的html页面 - 即使只是<html><head></head><body></body></html>(可能更少)..让我们称之为empty.html

如果您现在将Parent.html更改为

<html>
<body>
<script>
var ifr1 = document.createElement('iframe');

ifr1.onload = function() {
    alert("iframe 1 loaded") //fires on all browsers
    script = ifr1.contentWindow.document.createElement('script');
    script.src = 'PATH/TO/script.js';
    script.onload = function() {
        alert("script 1 onload") //fires on all browsers
    };
    ifr1.contentWindow.document.body.appendChild(script);
};
ifr1.src = 'empty.html'; // add this code *******
document.body.appendChild(ifr1);

</script>
</body>
</html>

然后按预期工作

不确定为什么firefox会做它的作用 - 可能是因为没有src属性,iframe的位置是about:blank - 但为什么第一个有效而不是第二个对我来说是个谜。

编辑:嗯,它曾经然后再次停止!!

好的,真的很奇怪 - 如果你添加ifr1.src = 'empty.html'就行了......如果你在script.js中复制它会再次中断

我不确定我是否已经回答你了,但至少我已经给了你一个工作的好处:p

答案 1 :(得分:0)

IMO这是Firefox中的一个错误,因为Firefox并没有像你期望的那样在iframe中执行load事件。 Mozilla的开发人员可能不同意。这一切都取决于你对什么&#34;加载&#34;的定义。应该意味着,而且比你想象的要复杂得多。

在任何情况下,真正的问题是何时知道访问ifr2.contentWindow的安全性,以及您使用ifr2.onload的方式的全部意义,以便您可以找出何时ifr2.contentWindow存在。

但请注意,在document.body.appendChild(ifr2)执行时会立即创建contentWindow和文档,因此,如果您将appendChild()调用移至当前代码上方并删除onload函数,则将按预期工作。

或者,您可以将onload函数更改为其他内容并在appendChild()后直接执行,如下所示:

var ifr2 = document.createElement('iframe');
function loadit() {
    console.log("iframe 2 loaded")
    script = ifr2.contentWindow.document.createElement('script');
    script.src = '...';
    script.onload = function() {
        console.log("script 2 onload")
    };
    ifr2.contentWindow.document.body.appendChild(script);
};

// add the iframe to the document
document.body.appendChild(ifr2);

// now execute your script stuff:
loadit()

这适用于所有(现代)浏览器。

答案 2 :(得分:0)

虽然这是一种不好的做法,并且在Chrome中已弃用(它会在控制台中显示警告)。 在添加脚本标记之前添加此行可以解决我的问题:

iframe.contentWindow.document.write('<html><head></head><body></body></html>');

似乎firefox需要它来初始化iframe并运行javascript ...