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

标签 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()”将一个脚本 block 附加到“theparent”。脚本 block 所做的只是调用 scriptDoneRunning(),它会提醒变量 blah。

想法是 scriptDoneRunning() 仅在 blah.js 完成执行后被调用。因为它在外部脚本元素之后附加到“theparent”,所以我希望它等待它完成,然后它会调用 scriptDoneRunning()。这是我预期的行为,但它只在 Firefox 中有效。在IE中alerted值为0,表示blah.js中的代码还没有执行。

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

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

谢谢!

最佳答案

脚本加载是异步的,你可以准确知道外部脚本何时加载,使用load(和readystatechange for IE)事件,但你应该小心删除 script 元素并在加载完成后使处理程序无效以避免已知的 memory leaks .

我还建议你在头部插入你的 script 元素,没有真正的原因(除非你使用 document.write 我不认为现在是个好主意)在 body...

中的任何位置添加脚本元素

我使用以下库独立函数,灵感来自 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);
}

关于javascript - javascript 执行顺序(内联和外部),IE 与 Firefox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1869919/

相关文章:

javascript - 如何将对象转换为对象数组

javascript - ColumnMapping.DataTableToObjectList 为我提供缺少时区信息的 DateTime 属性

javascript - 强制使用 enter 而不是在 javascript 中单击

JavaScript 即时编译

javascript - Angular 6 : Unable to access js variable in template getting async data

jquery - 无法使用 jQuery 更改选择值

java - 在流和 lambda 的帮助下将迭代解决方案转化为函数式解决方案

javascript - 页面加载前 childNodes 列表为空

javascript - 将 nsIDOMHTMLSelectElement 作为函数参数传递会导致异常

javascript - 当父级具有 "selected"类时如何更改图像 src?