浏览器什么时候执行 Javascript?执行光标如何移动?

IT技术 javascript ajax
2021-02-22 23:58:30

我想知道是否有任何可用资源描述浏览器的光标如何执行 Javascript。

我知道它会在页面加载时加载并执行标签,并且您可以将函数附加到各种窗口事件,但是当我通过 AJAX 检索远程页面并将其内容放入 div 时,事情变得模糊。

如果该远程页面必须加载诸如 的脚本库,那么<script src="anotherscript.js" />何时加载“anotherscript.js”并执行其内容?

如果我在当前页面上包含“anotherscript.js”,然后我加载了一些包含此脚本重复包含的远程内容,会发生什么情况?它会覆盖原来的吗?如果原始的“anotherscript.js”中有一个我改变了它的值的变量,然后我重新加载了那个文件……我会丢失原始值还是忽略了这个脚本的第二个包含?

如果我通过 AJAX 加载一些程序 Javascript,它什么时候执行?紧接着我做mydiv.innerHTML(remoteContent)什么?还是在此之前执行?

2个回答

答案取决于脚本标记的位置以及您添加它的方式:

  1. 与您的标记内嵌的脚本标记与浏览器对该标记的处理同步执行(除了,请参阅 #2),因此如果——例如——这些标记引用外部文件,它们往往会减慢页面的处理速度。(这是为了让浏览器可以处理document.write改变它们正在处理的标记的语句。)

  2. defer在某些浏览器上,具有该属性的脚本标记可能会在 DOM 完全呈现后才会执行。这些自然不能用document.write(同样,有一个async属性使脚本异步,但我不太了解它或它的支持情况;详细信息。)

  3. 在 DOM 加载(通过innerHTML和类似的)之后分配给元素的内容中的脚本标签根本不会执行,除非你使用像 jQuery 或 Prototype 这样的库来为你做这件事。(除了 Andy E 指出的一个例外:在 IE 上,如果它们有一个defer属性,它将执行它们。在其他浏览器中不起作用。)

  4. 如果通过 将实际script元素附加到文档Element#appendChild,浏览器会立即开始下载该脚本,并会在下载完成后立即执行。以这种方式添加的脚本不是同步执行的,也不是必须按顺序执行的。首先附加 a <script type="text/javascript" src="MyFct.js"></script>,然后附加很<script type="text/javascript">myFunction();</script>可能在远程(第一个)之前执行内联(第二个)一个。如果发生这种情况并MyFct.js声明myFunction(),当我们尝试将它与内联脚本一起使用时,它将不会被定义。如果您需要按顺序完成任务,您可以通过查看您添加元素上的loadreadyStateChange事件scriptload大多数浏览器上的事件,readyStateChange 在某些版本的 IE 上,有些浏览器两者都做,所以你必须处理同一个脚本的多个通知)。

  5. <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 上(我没有费心去检查其他人,我打算工作:-))。而如果您按此处所示附加元素,则会执行脚本。

@TJ Crowder:哇……感谢所有的细节和测试。我很确定当我使用 jQuery.html(...) 时它会立即执行脚本,但我没有意识到这是 jQuery 而不是默认的 javascript 行为。我想我需要查看 jQuery 代码,因为我很确定 API 指南没有提到这一点。
2021-04-15 23:58:30
@TJ:将defer属性添加innerHTML = 您尝试过示例中,然后在 IE 中重试:-)
2021-04-16 23:58:30
@Olga:我不知道有任何参考文献实际上用这么多词来表达它,尽管它很可能隐藏在scriptHTML5 规范部分的蜜糖深处:-) 但我知道这是真的,而且跨浏览器一致。
2021-04-25 23:58:30
@安迪:!!酷,谢谢!我不知道。:-) 看起来它只是 IE,不过。不过,很高兴知道。
2021-05-09 23:58:30
@RI:不用担心,我一路上捡到的东西。令人惊讶的是 jQuery 文档没有谈论它,但我也没有立即看到它。( docs.jquery.com/Attributes/html ) Prototype 的文档。
2021-05-12 23:58:30

如果您只是将包含脚本标签的 HTML 块用“innerHTML”填充到您的 DOM 中,则脚本标签根本不会被执行。当您使用 jQuery 之类的东西加载内容时,该库中的代码会显式地处理查找和执行脚本。

这并不十分准确,但您基本上可以将<script>标记的处理视为标记的全部内容(即脚本主体)都使用eval(). 如果脚本声明了全局(窗口)变量,则旧值将被覆盖。

脚本标签按照它们出现的顺序进行处理。当然,可以设置脚本块内的代码,以便它在初始执行时所做的将真正的处理推迟到以后。很多 jQuery 设置/初始化代码都可以做到这一点。

@TJ:如果你在它耳朵后面的正确位置抓挠它,Internet Explorer 就会:stackoverflow.com/questions/1891947/...
2021-04-16 23:58:30
好吧尝试一下:-) 我知道当 jQuery 检测到字符串参数html()中没有任何脚本标签时,它会明确地做不同的事情- 具体来说,它只使用innerHTML().
2021-04-20 23:58:30
@Adrian:Re “...我被告知innerHTML 将解析和执行JavaScript。这就是为什么你应该小心innerHTML...”好吧,如果那是什么,你永远不想将用户提供的内容直接分配给元素innerHTML你很小心,但我不知道浏览器会script在你这样做时执行标签(内联或引用外部文件)。
2021-04-20 23:58:30
有人告诉我,innerHTML 将解析并执行 JavaScript。这就是为什么您应该小心使用 innerHTML :) 但也许这仅适用于标签的内容,而不适用于 src= 中链接的 .js 文件?
2021-05-10 23:58:30