订购javascript执行(内联和外部),IE与Firefox

时间:2009-12-08 21:19:07

标签: javascript dom

我在下一页中遇到了javascript执行顺序的一些问题:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>

<script type="text/javascript">
    var blah = 0;

    function scriptDoneRunning()
    {
        alert(blah);
    }

    function addExternalScript(src, parentNode)
    {
        var sc = document.createElement('script');
        sc.setAttribute('type', 'text/javascript');
        sc.setAttribute('src', src);
        parentNode.appendChild(sc);
    }

    function addEndingScript(parentNode)
    {
        var theDiv = document.createElement('div');
        var sc = document.createElement('script');
        sc.setAttribute('type', 'text/javascript');
        sc.text = "scriptDoneRunning();";
        theDiv.appendChild(sc);
        parentNode.appendChild(theDiv);
    }
</script>
</head>

<body>
<div id="theparent">
    &nbsp;
</div>

<script type="text/javascript">
    addExternalScript("blah.js", document.getElementById("theparent"));
    addEndingScript(document.getElementById("theparent"));
</script>
</body>
</html>

而blah.js文件看起来像这样....

blah=3;

本质上,代码调用“addExternalScript()”,它将“blah.js”的脚本元素添加到“theparent”元素。 “blah.js”将变量blah设置为3。

然后我们调用“addEndingScript()”将脚本块附加到“theparent”。所有脚本块都是调用scriptDoneRunning()来警告变量blah。

我们的想法是,只有在blah.js执行完毕后才会调用scriptDoneRunning()。因为它会在外部脚本元素之后附加到“theparent”,我希望它等待它完成,然后它会调用scriptDoneRunning()。这是我期望的行为,但它只能在firefox中使用。在IE中,提醒的值为0,这意味着blah.js中的代码尚未执行。

这是页面实际上做的精简版本,所以显然这没有多大意义。但是有没有办法以这样的方式附加内联脚本:blah.js中的代码总是先在两个浏览器中执行?

此外,当部署它时,我将无法控制外部js。所以记住这一点;)

谢谢!

2 个答案:

答案 0 :(得分:4)

脚本异步加载,您可以使用load(和readystatechange for IE)事件确切地知道外部脚本的加载时间,但您应该注意删除{{1在加载完成后,使用元素并使处理程序无效,以避免已知的memory leaks

我还建议你将script元素插入头部,没有任何理由(除非你使用script我认为这不是一个好主意) document.write ...

内的任何位置的脚本元素

我使用以下独立于库的函数,受jQuery的$ .getScript方法的启发:

body

答案 1 :(得分:3)

这种行为的原因是,当您动态附加脚本标记时,IE会异步加载脚本(请查看链接MSDN)。要等到脚本加载,您应该使用“onload”(onreadystatechange)事件。

sc.onload = sc.onreadystatechange = function(){};

您可以使用我作为question的解决方案发布的加载程序,或者编写自己的加载程序。

P.S:当你想支持IE6&lt;时,使用setAttribute for src属性是不好的做法。浏览器,更好地使用直接属性,如

sc.src = "http://bla.js";