javascript执行顺序(内联和外部),IE与Firefox

javascript执行顺序(内联和外部),IE与Firefox,javascript,dom,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/javas

在下一页中,我对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>
本质上,代码调用addExternalScript,将blah.js的脚本元素添加到theparent元素中。js将变量blah设置为3

然后我们调用addEndingScript,它将脚本块附加到parent。脚本块所做的只是调用scriptDoneRunning,它会提醒变量blah

其思想是,只有在blah.js完成执行之后,才会调用scriptDoneRunning。因为它是在外部脚本元素之后附加到parent的,所以我希望它等待外部脚本元素完成,然后调用scriptDoneRunning。这是我所期望的行为,但是它只在firefox中起作用。在IE中,警报值为0,这意味着blah.js中的代码尚未执行

这是网页实际功能的精简版,显然这毫无意义。但是,有没有一种方法可以附加内联脚本,使blah.js中的代码始终在两种浏览器中首先执行

此外,当这个被部署时,我将无法控制外部js。所以请记住这一点


谢谢

脚本以异步方式加载,您可以使用IE事件的load和readystatechange准确地知道外部脚本加载的时间,但是您应该注意删除脚本元素,并在加载完成后使处理程序无效,以避免已知的错误

我还建议您在头部插入脚本元素,除非您使用document.write,否则没有真正的理由。我认为现在在正文中的任何位置添加脚本元素都不是一个好主意

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

loadScript("blah.js", function () {
  addEndingScript(document.getElementById("theparent"));
  // or why not simply scriptDoneRunning(); ???
});

function loadScript(url, callback) {
  var head = document.getElementsByTagName("head")[0],
      script = document.createElement("script"),
      done = false;

  script.src = url;

  // Attach event handlers for all browsers
  script.onload = script.onreadystatechange = function(){
    if ( !done && (!this.readyState ||
      this.readyState == "loaded" || this.readyState == "complete") ) {
      done = true;
      callback(); // execute callback function

      // Prevent memory leaks in IE
      script.onload = script.onreadystatechange = null;
      head.removeChild( script );
    }
  };
  head.appendChild(script);
}

脚本以异步方式加载,您可以使用IE事件的load和readystatechange准确地知道外部脚本何时加载,但是您应该注意删除脚本元素,并在加载完成后使处理程序为空,以避免已知的错误

我还建议您在头部插入脚本元素,除非您使用document.write,否则没有真正的理由。我认为现在在正文中的任何位置添加脚本元素都不是一个好主意

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

loadScript("blah.js", function () {
  addEndingScript(document.getElementById("theparent"));
  // or why not simply scriptDoneRunning(); ???
});

function loadScript(url, callback) {
  var head = document.getElementsByTagName("head")[0],
      script = document.createElement("script"),
      done = false;

  script.src = url;

  // Attach event handlers for all browsers
  script.onload = script.onreadystatechange = function(){
    if ( !done && (!this.readyState ||
      this.readyState == "loaded" || this.readyState == "complete") ) {
      done = true;
      callback(); // execute callback function

      // Prevent memory leaks in IE
      script.onload = script.onreadystatechange = null;
      head.removeChild( script );
    }
  };
  head.appendChild(script);
}

这种行为的原因是IE异步加载脚本,当您动态地附加脚本标记时,请检查链接。要等待脚本加载,应使用onload onreadystatechange事件

sc.onload = sc.onreadystatechange = function(){};
您可以使用加载程序,这是我发布的解决方案,也可以自己编写

另外,当你想支持IE6浏览器时,最好使用direct属性,比如

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

这种行为的原因是IE异步加载脚本,当您动态地附加脚本标记时,请检查链接。要等待脚本加载,应使用onload onreadystatechange事件

sc.onload = sc.onreadystatechange = function(){};
您可以使用加载程序,这是我发布的解决方案,也可以自己编写

另外,当你想支持IE6浏览器时,最好使用direct属性,比如

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

您需要在theparent div中使用元素有什么特别的原因吗?嗯,不太可能。我想它可以附在任何地方。只要blah.js先运行就可以了。您需要在theparent div中使用元素有什么特别的原因吗?嗯,不是真的。我想它可以附在任何地方。只要blah.js先运行就可以了。对于将来访问的人来说,将脚本放在头部不是最佳做法对于将来访问的人来说,将脚本放在头部不是最佳做法