【问题标题】:Strange javascript execution order IE9奇怪的javascript执行顺序IE9
【发布时间】:2013-11-07 10:49:36
【问题描述】:

我正在尝试加载具有某些功能的远程脚本并在 IE9 中内联执行它。 但是我遇到了一条错误消息,指出我的函数未定义。

归结为 IE9(似乎更低)以与我预期相反的顺序执行脚本。我做了一个简化的例子,但对我来说仍然产生同样的错误。

<script type="text/javascript" src="multibanner_rev04_tmp.js"></script>
<script type="text/javascript">alert('nr.2');</script>

为了便于阅读,我编辑了一个较长的脚本路径,它只有一个警报,没有别的。

警报“nr.2”在 IE9 中 multibanner_rev04_tmp.js 中的警报之前执行 我已经在多台装有 IE9 的计算机上进行了尝试,以确保它不是与此相同的问题:IE9 js load order and JQuery

问题似乎是一致的。还在 IE10 上尝试过此操作,它确实按预期顺序执行警报。

我真的不明白这里发生了什么,有什么想法吗?

【问题讨论】:

  • multibanner_rev04_tmp.js的内容是什么?没有它,这个问题就没有多大意义。
  • @T.J.Crowder 这只是一个警报,就像这样:alert('nr.1');
  • @jesper:再次:显示脚本。如果我有一个仅包含 alert("file"); 的脚本文件,并完全按照您在上面使用的方式使用它(后面是带有 alert("inline"); 的内联脚本),对于 IE9,我不会得到您描述的行为。我收到"file" 警报,然后是"inline" 警报。因此,如果您要声称确实如此,则必须展示一个完整的示例。这可能与您未展示的内容有关。
  • @jesper: 也不能用 IE8 或 IE6 复制(我手边没有 IE7)。 (您确实说过“而且似乎更低”)。我的测试用例:pastie.org/8462672(请注意,type 属性在上面没有任何作用,可以删除,但我想尽可能地复制你的测试用例。)
  • @jesper:没有doctype 也无法复制(以防在alert 周围有一些奇怪的怪癖):pastie.org/8462681

标签: javascript internet-explorer-8 internet-explorer-9


【解决方案1】:

根据您对问题的评论:

该脚本是使用另一个脚本(通过广告服务器)注入到我的页面上的,所以这可能是一个值得一试的问题。

这与您在问题中的实际情况完全不同。您在问题中的内容在标记中显示脚本标签; 注入 JavaScript 的脚本是完全不同的。

广告脚本可以通过两种方式将脚本添加到页面:

  1. 在主页面解析时使用document.write写出一个脚本标签。你说过你的页面是 XHTML 严格的。在主解析期间使用document.write 将标记输出到页面在XHTML 中无效,句号。你做不到。如果它完全有效,则行为是未指定的,您不应该依赖它。

    如果你想在主页面解析期间使用document.write,你必须停止使用XHTML。此时,脚本将按照解析器看到它们的顺序进行评估(不管它们是如何放入解析器的输入流中的,来自标记还是通过document.write)。

  2. 通过创建一个 script 元素 (document.createElement('script')),然后将其附加到 DOM。执行此操作时,脚本会在可用时立即进行评估。没有顺序。这就像在标记中使用 async attribute 一样(除了它更可靠地跨浏览器)。

    如果脚本是这样添加的,则不能依赖顺序。如果您控制以这种方式添加的脚本,您可以让该脚本检查其他脚本提供的任何内容,并使用setTimeout 将其执行推迟到其他内容出现为止。如果不这样做,您将不得不延迟添加脚本元素,直到您准备好为止。

【讨论】:

  • 你说得对,我当然应该考虑到这一点。抱歉,如果我的问题具有误导性。奇怪的是,我正在尝试做的事情确实适用于 Chrome、Firefox 和 IE10。我只是遇到了 IE9/IE8 的问题。
【解决方案2】:

(我第一次在 stackoverflow 上发帖...)

显而易见...第一个脚本标签要求浏览器加载单独的脚本文件 而第二个脚本标签有 javascript 内联(在 HTML 中)。

假设你有“alert('nr.1');”在你的 multibanner_rev04_tmp.js 的顶部,它看起来好像 IE9 首先执行内联代码,即使它 稍后出现在 HTML 中,根据以下情况,这是不正确的行为: http://www.w3.org/TR/html5/scripting-1.html#script

如果两个属性 [async 或 defer] 都不存在,那么脚本是 在用户代理继续之前立即获取并执行 解析页面。

但是,使用带有“IE9 标准”文档模式集的 IE10(我没有 IE9),我无法重现您所看到的行为,这有点指向 IE9 本身或特定版本中的错误IE9?我想知道如果将 defer="defer" 属性添加到第二个脚本标签会发生什么? (仅用于诊断,因为根据没有“src”属性的标准严格来说它是不合法的。)

【讨论】:

  • 我确实有“alert('nr.1');”在 multibanner_rev_tmp.js 中(事实上,这就是它现在包含的全部内容)。尝试添加延迟,这导致 IE9 根本不运行内联脚本。与真实浏览器相比,文档模式有时似乎有所不同,我在 IE8 上也遇到过这种情况。
  • 哦,欢迎来到stackoverflow!我想你可能在这里已经有一段时间了,但至少作为一个海报:)
  • 到目前为止只是一个冷漠的观察者。我注册只是能够 +1 有用的帖子比什么都多,但到目前为止甚至没有足够的声誉。感谢您的欢迎:-)
  • @Lqueryvg: “很明显……第一个脚本标签要求浏览器加载一个单独的脚本文件,而第二个脚本标签具有内联的 javascript(在 HTML 中)。” 是的,但是规范(以及长期的实践)非常很清楚,除非您使用 asyncdefer 属性,否则 HTML 中的脚本元素必须是 按顺序评估
  • @Lqueryvg:看起来你的答案被否决了。不要采取错误的方式。这个特定的答案是不正确的,但你显然是一个聪明的人,我希望你能继续努力帮助人们。
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2021-09-25
  • 2011-05-14
  • 1970-01-01
  • 2014-06-28
  • 2012-07-21
相关资源
最近更新 更多