使用iframe时是否有脚本执行顺序的规范?

时间:2015-05-12 09:33:37

标签: javascript html5 iframe

众所周知,浏览器会按照页面源中显示的顺序执行<script>个元素(禁止deferasync等)。我无法确定的是,是否有规范可以保证<iframe>元素之间的订单。

如果我的主页包含:

<html>
  <head>
    <script src="a.js"></script>
  </head>
  <body>
    <iframe src="inner.html" />
    <!-- ... -->
  </body>
</html>

使用inner.html:

<html>
  <head>
    <script src="b.js"></script>
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

规范中定义的 a.js之前b.js会执行吗?

如果主页面如下所示:

<html>
  <head>
    <script src="a.js"></script>
  </head>
  <body>
    <iframe src="inner.html" />
    <!-- ... -->
    <script src="c.js"></script>
  </body>
</html>

如果有保证的执行顺序是什么?说a.js需要很长时间才能加载 - 它保证在c.js之前仍然运行。但是,如果inner.html及其所有资源(包括b.js)在a.js之前加载了 - 那么HTML规范中是否有任何内容显示b.js <{1}}之前不会运行?如果它都是及时正常加载的,那么它是否在某个规范中定义a.js是否应该在b.js之前或之后执行?

我迄今为止设法找到的最好的the <iframe> spec是:

  

当iframe中的Document标记为已完全加载时,用户代理必须并行运行iframe加载事件步骤。

然而,这似乎只是说(当您深入了解&#34; iframe加载事件步骤&#34;)时,c.js事件将被分派到主页上运行的其他内容中,但是没有说明什么时候内部页面将被解析和内容加载以及(批判性地)何时在其中运行脚本。

2 个答案:

答案 0 :(得分:3)

script元素的specification对我来说似乎很清楚:

  

使用这些属性可以选择三种可能的模式。如果存在async属性,则script将在可用时立即执行,但不会阻止进一步解析页面。如果async属性不存在但存在defer属性,则在页面完成解析后执行script如果两个属性都不存在,则在用户代理继续解析页面之前,会立即获取并执行script

(强调补充。)

你问:

  

a.js需要很长时间才能加载 - 它保证在c.js之前仍然运行。但是,如果inner.html及其所有资源(包括b.js)在a.js之前加载了 - 那么HTML规范中的任何内容都表示b.js将在{{1}之前运行}}?

是的,我上面引用的部分暗示a.js不会在b.js之前运行。根据规范,解析将在获取并执行a.js时停止。在解析恢复之后,a.js的处理不会发生,这意味着iframe无法在b.js之前运行。

a.js可以在c.js之前执行。尽管如此,我可以指出没有一个简洁的段落来证明这一点。对此的解释贯穿整个说明书。会发生的是b.js触发导航到iframe中传递的网址。 (在规范中,这表示为“将元素的子浏览上下文导航到src。”导航被描述为here。)此导航事件将导致获取发生。 (描述获取here。)并且默认情况下并行执行提取。带有url的{​​{1}}元素也会提取一些数据,但是(没有scriptsrc会在提取时停止解析。< / p>

答案 1 :(得分:-2)

特定于chrome的说法,浏览器中加载的每个帧使用相同的渲染过程,但它们具有不同的上下文。 (请检查CEF3底层框架)。考虑到这一事实,只有单个进程负责iframe和大型机执行以及后续代码,我想我可以放心地说主帧首先加载然后加载子帧。 (可以检查我们从CEF3 CEF测试应用程序上获得的回调以再次确认)。 即首先执行a.js和c.js,然后执行b.js。

父HTML代码:

<head>
<script type="text/javascript">
window.abc = "ramesh";
</script>
</head>
<body>

<iframe id="iframeId" src="testiframe.html">
</iframe>

<script type = "text/javascript">
for (i=0;i<10000;i++) 
{
    console.log("something");
}
var p = document.getElementById("iframeId");
console.log(p.contentWindow.testValue);
</script>
</body>

iframe代码:

<script type="text/javascript">
window.testValue = "pqrs";
console.log("xyz");
</script>
<body>
</body>

iframe代码应该比我正在打印的for循环花费的时间少得多。但是这段代码总是首先从主框架打印控制台,如果我尝试从iframe的contentWindow访问testValue,它会显示未定义(这样做是为了检查它不是关于控制台日志打印顺序和实际的javascript执行顺序)。 p>

希望这会有所帮助。如果我在得出这个结论时错过了任何细节,请告诉我。