以下有问题的代码会导致Chrome和Firefox之间出现差异:
<button id="add">add element</button>
<div id="container"></div>
<script>
const c = document.querySelector("#container");
document.querySelector("#add").onclick = function() {
const iframe = document.createElement("iframe");
c.appendChild(iframe);
const h1 = document.createElement("h1");
h1.innerText = "hello";
iframe.contentDocument.body.appendChild(h1);
};
</script>
JSFiddle:https://jsfiddle.net/vtbcu1zj/
尝试在Chrome(应该可以正常运行)和Firefox(中断)中运行上述代码。
这似乎是因为Firefox不认为iframe会立即加载,而Chrome却认为。进行以下更改可使代码在两种浏览器中均可工作:
iframe.onload = function () {
iframe.contentDocument.body.appendChild(h1);
}
c.appendChild(iframe); // append after setting up event listener
这种差异的原因是什么?这是错误还是功能? Chrome是在这里做出错误的假设,还是Firefox处理不正确?
答案 0 :(得分:2)
Chrome错误,per specs,
[...],如果元素未指定src属性,并且用户代理正在“首次”处理iframe的属性
排队任务以运行iframe load event steps。
此任务的任务源是DOM操作任务源。
因此,他们实际上应该等待当前事件循环结束,然后再调用负责生成iframe文档的这些 iframe加载事件步骤。
在您致电iframe.contentDocument
的getter时,它应该已经返回null
。
但是实际上,作为作者,您应该等待onload
事件,该事件应始终异步触发。