【问题标题】:Chrome is synchronously handling iframe loading, whereas Firefox handles it asynchronouslyChrome 同步处理 iframe 加载,而 Firefox 异步处理
【发布时间】:2019-10-27 13:47:51
【问题描述】:

以下有问题的代码会导致 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 处理不正确?

【问题讨论】:

    标签: javascript html google-chrome firefox iframe


    【解决方案1】:

    Chrome 错了,per specs,

    [...] 如果元素没有指定 src 属性,并且用户代理正在“第一次”处理 iframe 的属性

      排队任务以运行iframe load event steps。
    该任务的任务源是DOM操作任务源。

    所以他们实际上应该等待当前事件循环完成,然后再调用这些负责生成 iframe 文档的 iframe 加载事件步骤。

    在您调用iframe.contentDocument getter 时,它应该返回了null。

    但实际上,作为作者,您应该等待onload 事件,该事件应该始终异步触发。

    【讨论】:

    • 这对我来说很有意义。 Chrome always (在我的许多用例中)似乎有它按时呈现和加载,这似乎有点奇怪。您是否有关于 iframe 加载过程并行性的信息来源?谢谢!
    • @Lucas-BetterCodingAcademy it's here,第二个项目符号“排队任务以运行 iframe 加载事件步骤。...”
    • 感谢您通知我!也许您可以修饰您的答案,以使其对可能面临类似问题的其他人提供更多信息。 :)
    • 是的,但实际上阅读它,我发现我弄错了......我对其他资源加载感到困惑,例如应该并行制作的 ,但这里的规范明确要求在这个在这种情况下,应该进行 queue a task 操作,即至少在下一个“进入事件循环”操作之前(即在我们的脚本执行结束之后)生成文档)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2017-06-03
    • 2011-05-30
    • 2016-04-29
    相关资源
    最近更新 更多