阻止IE加载动态包含的脚本两次 [英] Stop IE from loading dynamically included script twice

查看:194
本文介绍了阻止IE加载动态包含的脚本两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在misc中包含了一些相关内容。通过在< body> 标记的末尾添加< script> 标记来添加网页,然后加载其他javascript文件。这个流程有点复杂,所以在问我的问题之前我会尝试解释它:

I am including some related content on misc. web pages by adding a <script> tag near the end of the <body> tag, which then loads other javascript files. The flow is a little convoluted, so I’ll try to explain it before asking my question:


  • 浏览器加载我们的页面< script> 元素靠近< body> 元素的结尾

  • 脚本标记的src属性指向一个javascript文件(在某些情况下)注入第二个< script> 元素

  • 注入的< script> 元素的src属性指向另一个javascript文件,该文件最终会在页面的相应部分注入一些内容。

  • A browser loads a page with our <script> element near the end of the <body> element
  • The src attribute of the script tag points to a javascript file which (in some cases) injects a second <script> element
  • The src attribute of the injected <script> element points to yet another javascript file, which finally injects some content on the appropriate part of the page.

我们正在使用这种两阶段方法在决定是否包含最终内容之前能够进行一些基本处理,这可能需要一些时间才能加载。

We are using this two-stage approach to be able to do some basic processing before deciding whether to include the final content, which could take some time to load.

问题是IE8(可能是旧版本)加载最后一次javascript两次。似乎设置src属性的行为将触发加载,但是将脚本标记附加到DOM。有没有办法避免这种情况?

The problem is that IE8 (and maybe older versions) loads the last javascript twice. It appears that the act of setting the src attribute will trigger a load, but so will appending the script tag to the DOM. Is there any way to avoid this?

我创建了一个问题的简单演示。如果您有某种方式来跟踪HTTP请求,您将看到IE8加载js_test2.js两次。

I have created a bare-bones demo of the problem. If you have some way of tracing the HTTP requests, you will see that IE8 loads js_test2.js twice.

推荐答案

根本区别是IE在第一次将它添加到父元素的childNodes时执行脚本元素,无论父元素是否实际在文档中。其他浏览器只在将脚本添加到文档的childNodes树中的节点时执行脚本。

The root difference is that IE executes a script element the first time it is added to a parent element's childNodes, regardless of whether the parent element is actually in the document. Other browsers only execute script when it is added to a node inside the document's tree of childNodes.

jQuery的 domManip 函数(jQuery 1.3.2的第524行),由追加和其他类似的jQuery方法调用,试图变得聪明并调用 evalScript 对于在最终解析的HTML中找到的任何< script> 元素,执行脚本(如果外部脚本需要,通过执行AJAX请求)。 (实际的脚本元素已从已解析的childNodes中删除,以阻止它们在插入文档时执行,大概是这样只有当包含它们的内容一次附加到多个元素中时脚本才会执行一次。)

jQuery's domManip function (line 524 of jQuery 1.3.2), which is called by append and other similar jQuery methods, tries to be clever and calls evalScript for any <script> elements it finds in the final parsed HTML, to execute the script (by doing AJAX requests if necessary for external scripts). (The actual script elements have been removed from the parsed childNodes to stop them getting executed on insertion into the document, presumably so that scripts are only executed once when content containing them is appended into multiple elements at once.)

但是,因为之前的 clean 函数,在解析HTML时,将脚本元素附加到包装器div,IE已经执行了脚本。所以你得到两次执行。

However, because the previous clean function, whilst parsing the HTML, appended the script element to a wrapper div, IE will have already executed the script. So you get two executions.

最好的办法是避免使用 domManip 等函数,如

The best thing to do is avoid using domManip functions like append with HTML strings when you're doing anything with scripts.

实际上,忘记将内容放在序列化的HTML字符串中并获取jQuery来解析它;只需要更可靠的纯DOM方式:

In fact, forget putting your content in a serialised HTML string and getting jQuery to parse it; just do it the much more reliable plain DOM way:

var s= document.createElement('script');
s.type= 'text/javascript';
s.charset= 'UTF-8';
s.src= 'js_test2.js';
document.getElementById('some_container').appendChild(s);

(老实说,在查看了的胃部流失源代码之后干净的功能,我对使用jQuery的基于HTML字符串的DOM操作完全有疑问。它应该修复浏览器错误,但是哑弹正则表达式处理在我看来很可能引起尽可能多的问题。)

(To be honest, after viewing the stomach-churning source code of the clean function, I'm having serious doubts about using jQuery's HTML-string-based DOM manipulations for anything at all. It's supposed to fix up browser bugs, but the dumb-regex processing seems to me likely to cause as many problems as it solves.)

顺便提一下这个初始电话:

Incidentally with this initial call:

document.write(unescape("%3Cscript src='js_test1.js' type='text/javascript'%3E%3C/script%3E"));

你不需要在这里unescape;我不知道为什么这么多人这么做。在内联脚本中需要避免序列< / ,因为它会结束< script> 标记,如果你正在做XHTML < & 也应该避免(或 ]]> 如果您正在使用CDATA包装器),但只需使用JavaScript字符串文字就可以更轻松地完成所有操作:

You don't need to unescape here; I don't know why so many people do. The sequence </ needs to be avoided in an inline script as it would end the <script> tag, and if you're doing XHTML < and & should be avoided too (or ]]> if you're using a CDATA wrapper), but there's an easier way of doing all that with just JavaScript string literals:

document.write('\x3Cscript src="js_test1.js" type="text/javascript">\x3C/script>"));

这篇关于阻止IE加载动态包含的脚本两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆