我有以下脚本,其中第一个和第三个 document.writeline 是静态的并且 第二个已生成:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

Firefox 和 Chrome 将显示 , 期间, ,而 Internet Explorer 首先显示 期间 然后才显示 .

我遇到过 一篇文章指出 我不是第一个遇到这种情况的人,但这并没有让我感觉好一点。

有谁知道如何在所有浏览器中将顺序设置为确定性,或者破解 IE 以像所有其他正常浏览器一样工作?

注意事项:代码片段是一个非常简单的重现。它是在服务器上生成的,第二个脚本是唯一发生变化的内容。这是一个很长的脚本,之所以在它之前和之后有两个脚本,是为了让浏览器缓存它们,并且代码的动态部分会尽可能小。它也可能使用不同的生成代码在同一页面中多次出现。

有帮助吗?

解决方案 2

我找到了更符合我喜好的答案:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript'>alert('during');<\/sc" + "ript>");
document.write("<script defer language='javascript' type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

这将推迟两者的加载 期间 直到页面加载完成。

我想这已经是我能得到的最好的了。希望有人能够给出更好的答案。

其他提示

不,这是 Internet Explorer 的行为。

如果动态附加脚本,IE、Firefox 和 Chrome 都会以异步方式下载脚本。

Firefox 和 Chrome 将等待所有异步请求返回,然后按照脚本在 DOM 中附加的顺序执行脚本,但 IE 按照通过网络返回的顺序执行脚本。

由于与外部 JavaScript 文件相比,警报“检索”所需的时间更少,这可能解释了您所看到的行为。

来自克里斯托弗·亨里克森 关于异步脚本加载主题的帖子:

在这种情况下,即IE和Firefox将下载两个脚本,但是Internet Explorer也将按照他们完成下载的顺序执行它们,而Firefox则不同步,但仍按照它们附加在DOM中的顺序执行它们。

在Internet Explorer中,这意味着您的脚本不能彼此依赖,因为执行订单会因网络流量,缓存等方面而有所不同。

考虑使用 Javascript 加载器。它将允许您指定脚本依赖性和执行顺序,同时还可以异步加载脚本以提高速度并消除一些浏览器差异。

这是对其中一些的很好的概述: 基本 JavaScript:前五个脚本加载器.

我使用过 RequireJS 和 LabJS。在我看来,LabJS 没有那么固执己见。

幻灯片 25/26(共 25/26) 这个演示文稿 谈谈不同插入脚本方法的特点。这表明 IE 是唯一能够按顺序执行这些脚本的浏览器。所有其他浏览器将按照它们完成加载的顺序执行它们。如果一个或多个具有内联 js 而不是 src,即使 IE 也不会按顺序执行它们。

建议的方法之一是插入一个新的 DOM 元素:

var se1 = document.createElement('script');
se1.src = 'a.js';

var se2 = document.createElement('script');
se2.src = 'b.js';

var se3 = document.createElement('script');
se3.src = 'c.js';

var head = document.getElementsByTagName('head')[0]
head.appendChild(se1);
head.appendChild(se2);
head.appendChild(se3);

要生成第二个脚本部分,您可以使用脚本来生成该内容并传递参数:

se2.src = 'generateScript.php?params=' + someParam;

编辑:尽管我发布的文章是这么说的,但我的测试表明,如果每个浏览器都有 src,大多数浏览器都会按顺序执行 document.write 脚本,因此,虽然我认为上面的方法是首选方法,但您也可以这样做:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

再次编辑(回复对我自己和其他人的评论):您已经在页面上生成了脚本。无论您正在做什么,都可以移动到另一个生成相同代码块的服务器端脚本。如果您的页面上需要参数,请将它们传递给查询字符串中的脚本。

此外,如果按照您的建议,您多次生成内联脚本,则可以使用相同的方法:

<script language="javascript" type="text/javascript">
document.write("<script type='text/javascript' src='before.js'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params1 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params2 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='during.php?params=" + params3 + "'><\/sc" + "ript>");
document.write("<script type='text/javascript' src='after.js'><\/sc" + "ript>");
</script>

然而,这开始看起来好像你正在以错误的方式处理这个问题。如果您多次生成一大段代码,那么您可能应该将其替换为单个 js 函数,并使用不同的参数调用它......

好吧……期间……

// During.js
during[fish]();

后...

// After.js
alert("After");
fish++

超文本标记语言

<!-- some html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>
<!-- some other html -->
<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript' src='before.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript'>during[" + fish + "] = function(){alert('During!' + fish);}</sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='during.js'></sc" + "ript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'></sc" + "ript>");
</script>

不过,我倾向于同意这种气味开始出现的方式。特别是,为什么不能将“during”代码生成到动态创建的 js 文件中,然后将其插入?

请注意,动态生成的脚本会 里面 中的函数 第二 文档.写。
在 FF2、IE7 中测试

您可以通过在脚本上定义“onload”(或类似)事件并在事件函数中注入下一个事件来强制顺序执行。这并不是微不足道的,但是有很多例子,这里是一个。

http://www.phpied.com/javascript-include-ready-onload/

我认为像 jQuery 或原型这样的流行库可以帮助解决这个问题。

提供代码:

<script language="javascript" type="text/javascript">
document.write("<script language='javascript' type='text/javascript'>function callGeneratedContent() { alert('during'); }<\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='before.js'><\x2Fscript>");
document.write("<script language='javascript' type='text/javascript' src='after.js'><\x2Fscript>");
</script>

在 before.js 中:

alert("Before");
callGeneratedContent();

在 after.js 中:

alert("After");

你必须把生成的行放在前面,否则 FF 会抱怨,因为它在看到函数定义之前执行了 before.js 。

那个怎么样:

<script>
document.write("<script src='before.js'><\/script>");
</script>

<script >
document.write("<script>alert('during');<\/script>");
</script>

<script>
document.write("<script src='after.js'><\/script>");
</script>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top