我想知道是否有任何可用资源描述浏览器的光标如何执行Javascript。
我知道它会在页面加载时加载并执行标记,并且您可以将函数附加到各种窗口事件,但事情变得模糊的是,例如,我通过AJAX检索远程页面并将其内容放入格。
如果该远程页面必须加载<script src="anotherscript.js" />
等脚本库,何时加载“anotherscript.js”并且其内容正在执行?
如果我在当前页面上包含“anotherscript.js”,然后我加载了一些包含此脚本的重复内容的远程内容,会发生什么?它会覆盖原来的吗?如果原始的“anotherscript.js”中有一个var,其值已更改,然后我重新加载该文件...我会丢失原始值还是忽略该脚本的第二个包含该怎么办?
如果我通过AJAX加载一些程序性Javascript,它什么时候执行?我mydiv.innerHTML(remoteContent)
之后立即?还是在此之前执行?
答案 0 :(得分:53)
答案取决于脚本标记的位置以及添加方式:
与标记内联的脚本标记与浏览器对该标记的处理同步执行(除了,参见#2),因此,如果 - 例如 - 这些标记引用外部文件,它们往往会减慢页面的处理。 (这样浏览器就可以处理document.write
语句,这会改变他们正在处理的标记。)
在某些浏览器上,具有defer
属性的脚本标记在完全呈现DOM之后才能执行。当然,这些不能使用document.write
。 (类似地,有一个async
属性使脚本异步,但我不太了解它或它的支持程度如何; details。)
在DOM加载(通过innerHTML
之后)分配给元素的内容中的脚本标记根本不会被执行,除非您使用像jQuery或Prototype这样的库来为您完成。 (Andy E指出一个例外:在IE上,如果它们具有defer
属性,它将执行它们。在其他浏览器中不起作用。)
如果您通过Element#appendChild
将实际script
元素附加到文档,浏览器会立即开始下载该脚本,并在下载完成后立即执行。以这种方式添加的脚本不会同步执行或必须按顺序执行。首先附加<script type="text/javascript" src="MyFct.js"></script>
,然后附加<script type="text/javascript">myFunction();</script>
可以在远程(第一个)之前执行内联(第二个)。如果发生这种情况并MyFct.js
声明myFunction()
,则在我们尝试将其与内联脚本一起使用时,将不会定义它。如果您需要按顺序完成任务,可以通过观察添加的load
元素上的readyStateChange
和script
事件来判断加载远程脚本的时间(load
是大多数浏览器上的事件,某些版本的IE上有readyStateChange
,有些浏览器同时执行这两种操作,因此您必须处理同一脚本的多个通知。)
当相关事件发生时,将执行属性(<a href='#' onclick='myNiftyJavaScript();'>
)上的事件处理程序内的脚本而不是脚本标记中的脚本。
我正在努力工作,突然我的后脑说:“你知道,你已被告知如果你将它们分配到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>
来自脚本的警报不会出现在IE7,FF3.6或Chrome4上(我没有费心去检查别人,我打算工作:-))。而如果你附加如here所示的元素,脚本就会被执行。
答案 1 :(得分:3)
如果您只是使用“innerHTML”将包含脚本标记的HTML块填充到DOM中,则根本不会执行脚本标记。当您使用jQuery之类的东西加载东西时,该库中的代码显式处理查找和执行脚本。
这并不准确,但你基本上可以想到<script>
标签的处理,好像标签的整个内容(即脚本体)是用eval()
执行的。如果脚本声明了全局(窗口)变量,则会覆盖旧值。
脚本标记按其出现的顺序处理。当然,可以设置脚本块内的代码,以便在初始执行时执行的操作是将实际处理推迟到以后。很多jQuery设置/初始化代码都会这样做。