Javascript 浏览器什么时候执行Javascript?执行光标如何移动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2342974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When does the browser execute Javascript? How does the execution cursor move?
提问by aw crud
I was wondering if there are any available resources that describe how a browser's cursor executes Javascript.
我想知道是否有任何可用资源描述浏览器的光标如何执行 Javascript。
I know it loads and executes tags when a page loads, and that you can attach functions to various window events, but where things get fuzzy is when, for instance, I retrieve a remote page via AJAX and put its contents into a div.
我知道它会在页面加载时加载并执行标签,并且您可以将函数附加到各种窗口事件,但是当我通过 AJAX 检索远程页面并将其内容放入 div 时,事情变得模糊。
If that remote page has got to load script libraries such as <script src="anotherscript.js" />, when is "anotherscript.js" being loaded and its contents are being executed?
如果该远程页面必须加载诸如 的脚本库,那么<script src="anotherscript.js" />何时加载“anotherscript.js”并执行其内容?
What happens if I included "anotherscript.js" on my current page, and then I load some remote content which has a duplicate include of this script? Does it overwrite the original one? What if the original "anotherscript.js" has a var in it whose value I altered, and then I reload that file... do I lose the original value or is the second inclusion of this script ignored?
如果我在当前页面上包含“anotherscript.js”,然后我加载了一些包含此脚本重复包含的远程内容,会发生什么情况?它会覆盖原来的吗?如果原始的“anotherscript.js”中有一个变量,我改变了它的值,然后我重新加载该文件...我会丢失原始值还是忽略此脚本的第二个包含?
If I load some procedural Javascript via AJAX, when is it executed? Immediately after I do mydiv.innerHTML(remoteContent)? Or is it executed before that?
如果我通过 AJAX 加载一些程序化 Javascript,它什么时候执行?紧接着我做mydiv.innerHTML(remoteContent)什么?还是在此之前执行?
采纳答案by T.J. Crowder
The answer varies depending on where the script tag is and how you've added it:
答案取决于脚本标记的位置以及您添加它的方式:
Script tags inline with your markup are executed synchronously with the browser's processing of that markup (except, see #2), and so if -- for instance -- those tags reference external files, they tend to slow down the processing of the page. (This is so the browser can handle
document.writestatements, which change the markup they're processing.)Script tags with the
deferattribute may, on some browsers, not be executed until after the DOM has been fully rendered. Naturally these can't usedocument.write. (Similarly there's anasyncattribute that makes the script asynchronous, but I don't know much about it or how well it's supported; details.)Script tags in content you assign to elements after DOM load (via
innerHTMLand similar) are not executed at all, barring your use of a library like jQuery or Prototype to do it for you. (With one exception pointed out by Andy E: On IE, if they have adeferattribute, it will execute them. Doesn't work in other browsers.)If you append an actual
scriptelement to the document viaElement#appendChild, the browser begins downloading that script immediately and will execute it as soon as the download is finished. Scripts added this way are not executed synchronously or necessarily in order. First appending a<script type="text/javascript" src="MyFct.js"></script>, and then appending<script type="text/javascript">myFunction();</script>may well execute the inline (second) one before the remote (first) one. If that happens andMyFct.jsdeclaresmyFunction(), it will not be defined when we try to use it with the inline script. If you need things done in order, you can tell when a remote script has been loaded by watching theloadandreadyStateChangeevents on thescriptelement you add (loadis the event on most browsers,readyStateChangeon some versions of IE, and some browsers do both, so you have to handle multiple notifications for the same script).Script inside event handlers on attributes (
<a href='#' onclick='myNiftyJavaScript();'>) rather than in a script tag is executed when the relevant event occurs.
与您的标记内嵌的脚本标记与浏览器对该标记的处理同步执行(除了,请参阅 #2),因此如果 - 例如 - 这些标记引用外部文件,它们往往会减慢页面的处理速度。(这是为了让浏览器可以处理
document.write语句,这些语句会更改它们正在处理的标记。)defer在某些浏览器上,具有该属性的脚本标记可能会在 DOM 完全呈现后才会执行。这些自然不能用document.write。(同样有一个async属性使脚本异步,但我不太了解它或它的支持情况;详细信息。)在 DOM 加载(通过
innerHTML和类似的)之后分配给元素的内容中的脚本标签根本不会执行,除非你使用像 jQuery 或 Prototype 这样的库来为你做这件事。(除了 Andy E 指出的一个例外:在 IE 上,如果它们有一个defer属性,它将执行它们。在其他浏览器中不起作用。)如果通过 将实际
script元素附加到文档Element#appendChild,浏览器会立即开始下载该脚本,并会在下载完成后立即执行。以这种方式添加的脚本不是同步执行的,也不是必须按顺序执行的。首先附加 a<script type="text/javascript" src="MyFct.js"></script>,然后附加很<script type="text/javascript">myFunction();</script>可能在远程(第一个)之前执行内联(第二个)一个。如果发生这种情况并MyFct.js声明myFunction(),当我们尝试将它与内联脚本一起使用时,它将不会被定义。如果您需要按顺序完成任务,您可以通过查看您添加的元素上的load和readyStateChange事件script(load大多数浏览器上的事件,readyStateChange在某些版本的 IE 上,有些浏览器两者都做,所以你必须处理同一个脚本的多个通知)。<a href='#' onclick='myNiftyJavaScript();'>当相关事件发生时,将在属性 ( ) 而不是脚本标记中的事件处理程序中执行脚本。
I was working away at my Real Job and suddenly my hindbrain said "You know, you've been toldthey won't be executed if you assign them to innerHTML, but have you personally checked?" And I hadn't, so I did -- FWIW:
我正在做真正的工作,突然我的后脑说:“你知道,你被告知如果你把它们分配给innerHTML,它们不会被处决,但你有没有亲自检查过?” 我没有,所以我做了 - FWIW:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Script Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript'>
function addScript()
{
var str, div;
div = document.getElementById('target');
str = "Content added<" + "script type='text/javascript'>alert('hi there')<" + "/" + "script>";
alert("About to add:" + str);
div.innerHTML = str;
alert("Done adding script");
}
</script>
</head>
<body><div>
<input type='button' value='Go' onclick='addScript();'>
<div id='target'></div>
</div></body>
</html>
The alert from the script doesn't appear on IE7, FF3.6, or Chrome4 (I haven't bothered to check others, I'm meant to be working :-) ). Whereas if you append elements as shown here, the script gets executed.
来自脚本的警报不会出现在 IE7、FF3.6 或 Chrome4 上(我没有费心去检查其他人,我打算工作:-))。然而,如果您按此处所示附加元素,则会执行脚本。
回答by Pointy
If you just stuff a block of HTML containing script tags into your DOM with "innerHTML", the script tags won't be executed at all. When you load stuff with something like jQuery, code in that library explicitly handles finding and executing the scripts.
如果您只是使用“innerHTML”将包含脚本标签的 HTML 块填充到您的 DOM 中,则脚本标签根本不会被执行。当您使用 jQuery 之类的东西加载内容时,该库中的代码会显式地处理查找和执行脚本。
It's not precisely accurate, but you can basically think of the processing of a <script>tag as if the whole contents of the tag (i.e., the script body) were executed with eval(). If the script declares global (window) variables, then old values are overwritten.
它并不完全准确,但您基本上可以将<script>标记的处理视为标记的全部内容(即脚本主体)都使用eval(). 如果脚本声明了全局(窗口)变量,则旧值将被覆盖。
Script tags are processed in the order that they appear. Of course the code inside the script blocks may be set up so that what it does upon initial execution is to defer the realprocessing until later. Lots of jQuery setup/initialization code will do that.
脚本标签按照它们出现的顺序进行处理。当然,可以设置脚本块内的代码,以便它在初始执行时所做的是将真正的处理推迟到以后。很多 jQuery 设置/初始化代码都可以做到这一点。

