3

我知道 JS 是单线程和同步执行的。因此,当我将文件添加到浏览器头标记时,该文件会在遇到时立即执行。然后它转到下一个脚本标签并执行该文件。我的问题是当我将 js 文件动态添加到 HTML 头标记时。浏览器如何执行该文件?是否就像在当前执行所在的任何位置加载文件后立即执行文件一样。还是我们可以控制该文件的执行方式?

4

4 回答 4

3

脚本加载完毕后,会尽快执行。也就是说,如果其他一些 javascript 函数正在执行,比如 clickhandler 或其他什么,它将被允许首先完成 - 但这是给定的,因为正如你所说,在浏览器中 JavaScript 通常在单个线程中执行。

您无法控制脚本加载的那部分,但您可以使用这种模式 - 深受 JSONP 的启发:

插入脚本:

(function () {
    var module = {
        init: function () {
            /* ... */
        }
    }

    ready(module);  // hook into "parent script"
}());

主页上的脚本:

function ready(o) {
    // call init in loaded whenever you are ready for it...
    setTimeout(function () { o.init(); }, 1000);
}

这里的关键是ready在您的页面上定义的函数,并从您动态插入的脚本中调用。init脚本不会立即开始执行,而是只会告诉父页面它已加载,然后父页面可以在想要开始执行时回调插入的脚本函数。

于 2012-04-22T12:22:23.290 回答
3

动态加载 JavaScript 文件时会发生什么(非常简化,没有检查):

  1. 文件已加载;
  2. 如果有函数调用,例如doSomething()or (function(){...})(),则执行代码(当然你必须有定义);
  3. 如果只有函数定义,则在函数调用之前什么都不会发生。

看这个例子:3个文件被加载,2个立即执行,1个等待超时。

编辑:

脚本标签可以放置在页面的任何位置。实际上如果不使用onload事件最好放在页面末尾(雅虎速度提示)。

使用 HTML5 JavaScript 有 web workers MDN MSDN wikipedia

于 2012-04-22T13:34:24.270 回答
1

考虑一种方法是

var js=document.createElement('script')
js.setAttribute("type","text/javascript")
js.setAttribute("src", filename)
document.getElementsByTagName("head")[0].appendChild(js); 
// ^ However this technique has been pointed to be not so trusworthy (Read the link in the comment by Pomeh)

但是回答你的问题

浏览器如何执行该文件?

一旦脚本被添加到 DOM

是否就像在当前执行所在的任何位置加载文件后立即执行文件一样?

是的

还是我们可以控制该文件的执行方式?

如果您附加一个 onload 事件处理程序,而不是一个讨厌的技巧,它会更好。

于 2012-04-22T12:19:36.207 回答
-3

这是一些您可以尝试回答问题的代码。

<script>
var s = document.createElement('script'), f = 1;
s.src="http://code.jquery.com/jquery-1.7.2.js";
document.head.appendChild(s)
s.onload = function(){
  console.log(2);
  f = 0    
}
while(f){
    console.log(1);
}
</script>

理想情况下,此代码应在脚本加载时打印 2,但如果您注意到,这永远不会发生 ​</p>

注意:这会杀死你的浏览器!

于 2012-04-22T12:16:08.097 回答