JavaScript:DOM 加载事件、执行顺序和 $(document).ready()

IT技术 javascript jquery events dom
2021-01-27 16:19:21

我刚刚意识到我缺乏对页面加载到浏览器时到底发生了什么的基本知识。

假设我有这样的结构:

<head>

<script src="jquery.js" type="text/javascript"></script>
<script src="first.js" type="text/javascript"></script>
</head>
<body>
...
<script type="text/javascript" id="middle">
    // some more JS here...
</script>
...
<script src="last.js" type="text/javascript"></script>
</body>

以下是我的问题:

  1. 事情发生的顺序是什么?首先执行 DOM 然后执行 JS,是反之亦然,还是同时执行(或在 JS 文件下载完成后立即执行,不考虑 DOM)?我知道脚本是按顺序加载的。

  2. $(document).ready()适合放在哪里在 Firebug 的 Net 选项卡中,我看到了DOMContentLoaded事件和load事件。$(document).ready()当触发DOMContentLoaded事件触发?找不到关于此的任何具体信息(每个人都只提到“加载 DOM 时”)。

  3. “加载 DOM 时”究竟是什么意思?所有的 HTML/JS 都已经被浏览器下载并解析了吗?或者只是HTML?

  4. 以下场景是否可能:有一个$(document).ready()调用 中的代码last.js,但在加载 last.js 之前运行?它最有可能在哪里(在first.js或内联代码块中)?我怎样才能防止这种情况?

我想了解什么时候发生什么以及什么取决于什么(如果有的话)的大局。

3个回答

Javascript 是按原样执行的。 通常,浏览器一看到<script>标签就停止解析页面,下载并运行脚本,然后继续运行。这就是为什么通常建议将<script>标签放在底部的原因:这样在浏览器等待脚本下载时用户不会有空白页面。

但是,从 Firefox 3.5 开始,脚本在后台下载,而页面的其余部分则呈现。在脚本使用document.write或类似的现在不寻常的事件中,Firefox 将根据需要进行备份和重绘。我不认为其他浏览器目前会这样做,但如果它即将到来我不会感到惊讶,并且 IE 至少支持标签中的一个defer属性<script>,它将延迟加载脚本直到页面加载后。

DOMContentLoaded就是这样:它在 DOM 加载后立即触发。也就是说,一旦浏览器解析了所有的 HTML 并在内部创建了它的树。它不会等待图像、CSS 等加载。DOM 是您运行任何您想要的 Javascript 所需的全部内容,因此不必等待其他资源就好了。但是,我相信只有 Firefox 支持DOMContentLoaded在其他浏览器中,ready()只会将事件附加到常规的 old onload

Javascript 保证按照它在 HTML 中出现的顺序运行,因此在尝试将其附加到事件之前,请确保已定义您的函数。

实际上,虽然将脚本放在底部有帮助,但它们仍然必须在页面加载之前执行。异步加载它们要好得多,这意味着即使将它们放在顶部,浏览器也会继续并行解析页面和加载脚本。唯一的问题是您将不再知道脚本的执行顺序。
2021-03-23 16:19:21
我在 IE9 上测试了一个 aspx 页面(从开发人员工具模拟),脚本从 <head> 的开头移动到 <body> 的结尾,发现脚本在 head 内部时加载时间更快。记录加载视频以衡量用户体验。对我来说没有明确的赢家
2021-04-09 16:19:21
很有意思。感谢前瞻视角!
2021-04-10 16:19:21
  1. 所有包含的脚本都是为了它们出现在 html 中而发生的,它们在解析 html 时被加载。
  2. 这意味着所有 dom 对象都已加载,并且都包含脚本和 css。(图像可能还没有)。
  3. 见2。
  4. $(document).ready() 只有在所有脚本和 dom 对象都加载后才会被调用,你应该没问题。

http://javascript.about.com/od/hintsandtips/a/exeorder.htm应该可以帮助您回答这个问题

基本上:首先加载所有数据(html),然后首先执行头/主体中的 js 代码,这些代码不在函数中或就绪或类似的东西中。从那里开始按顺序处理脚本

重要的是要注意 js 优先于 ie。css 加载 - 因此从性能角度来看,您应该在页面底部放置 js。

所以@4:你不需要阻止这种情况,因为 first.js 总是在 last.js 之前被读取/执行