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

Posted

技术标签:

【中文标题】JavaScript:DOM 加载事件、执行顺序和 $(document).ready()【英文标题】:JavaScript: DOM load events, execution sequence, and $(document).ready() 【发布时间】:2010-11-21 10:20:46 【问题描述】:

我刚刚意识到我缺乏关于将页面加载到浏览器中究竟发生什么的基本知识。

假设我有这样的结构:

<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>

以下是我的问题:

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

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

    “加载 DOM 时”究竟是什么意思?浏览器是否已下载并解析了所有 html/JS?还是只是 HTML?

    是否可能出现以下情况:有一个$(document).ready() 调用last.js 中的代码,但在last.js 加载之前运行?它最有可能在哪里(在first.js 或内联代码块中)? 如何防止这种情况发生?

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

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

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

【讨论】:

【参考方案3】:

http://javascript.about.com/od/hintsandtips/a/exeorder.htm 应该会帮你回答这个问题

基本上: 首先加载所有数据(html),然后是 js 头/正文中的代码不在函数中或未准备好或类似的东西首先执行。从那里开始按顺序处理脚本

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

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

【讨论】:

以上是关于JavaScript:DOM 加载事件、执行顺序和 $(document).ready()的主要内容,如果未能解决你的问题,请参考以下文章

onload 事件DOMContentLoaded事件DOM加载顺序

页面加载顺序及触发的事件

页面加载时触发的事件及顺序

HTML 学习笔记 JavaScript(事件)

javascript原生判断DOM是否加载完毕执行方法

javascript中的事件冒泡事件捕获和事件执行顺序