$(document).ready()何时激发


When does $(document).ready() fire?

这个问题的评论让我思考了一些问题。$(document).ready()功能究竟何时启动?显而易见的答案是"文件什么时候准备好",但具体是什么时候?

例如,如果我打开输出缓冲并在PHP继续执行时刷新我的输出,那不是会将输出发送到浏览器吗?那么,在PHP脚本完成执行之前,文档是否可以准备好,或者事件是否要等到请求完成?


编辑:

响应似乎基本上一致认为,当客户认为事件已准备好时,事件就会启动。

为了更好地理解(我可能一开始就应该这样做),我只设置了一个测试:

<?php ob_start(); ?>
<html>
<head>
    <script type="text/javascript" src="lib/js/jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            alert("READY");
        });
    </script>
</head>
<body>
<?php
    ob_flush();
    for ($i=0; $i<999999; $i++) {
        echo "HELLO$i'n";
        ob_flush();
    }
?>
</body>
</html>

结果是,在本例中,内容立即开始显示在页面上,但直到循环完成或脚本超时(30秒)才发出警报。

根据您使用的浏览器,我尝试在循环中插入以下内容:

if ($i == 99) {
    echo "</body></html>";
}

Chrome似乎可以通过将这些标签放在页面末尾来自动更正(如web开发检查器中所示)。查看页面的来源显示它在中间,我在那里回声了它。一旦jQuery确定DOM可访问,

jQuery的文档ready事件就会触发。具体机制取决于浏览器。

请查看相关的源代码。

首先,检查在尝试将侦听器绑定到事件时DOM是否已经可访问。如果是的话,回调被安排为立即触发-尽管它们实际上并没有立即触发,以允许已经占用当前执行槽的代码在需要时取消处理程序。

如果DOM尚不可访问,则会尝试将事件侦听器绑定到浏览器的本地DOMContentLoaded事件-这是要求浏览器在DOM可用时通知您的"正确"本地方式,但这是一个相对现代的功能。如果这是不可能的(这几乎可以肯定地表明你的代码运行在旧版本的IE中),代码会回到几个机制:

  • 尝试附加到文档的onreadystatechange事件。这不是傻瓜式的,而且会比DOMContentLoaded晚,但它非常好
  • 回退到window对象的load事件。这通常会比DOM可用的时间晚得多,但这是确保事件最终总是启动的最后一搏
  • 最坏的情况是:继续轮询DOM,直到它可以访问为止

从PHP的角度来看,在PHP脚本执行完成之前,可能发生(但不太可能)。在某些情况下(例如长轮询),事件会在脚本完成之前触发,但这种情况只会发生在较旧的浏览器中。然而,在这些场景中,您根本不会(不应该)使用这些事件,只需在页面的主体中放置适当的<script>元素,就可以在加载后立即执行它们,而无需等待DOM的其余部分。

就我个人而言,我从来没有使用过这些负载驱动的事件,或多或少是出于这个原因。YMMV。

例如,如果我打开输出缓冲并在PHP继续执行时刷新我的输出,那不是会将输出发送到浏览器吗?

是的,它会发送输出,但这并不意味着浏览器认为服务器已经完成。我知道它不是PHP,但我喜欢Perl文章《缓冲区的痛苦》。当UserAgent认为文档已准备就绪时,文档已准备好。然而,浏览器将保持套接字打开,同时它仍然认为自己正在接收数据,并且没有发送END信号。

那么,在PHP脚本完成执行之前,文档是否可以准备好,或者事件是否要等到请求完成?

通常,浏览器将等待,直到服务器完成发送数据。如果您正在刷新输出,那么在脚本仍在运行时,web服务器可能会超时,例如,我认为Apache默认为2分钟。如果服务器发送结束信号,则说明文档已经完成,浏览器可能会准备DOM并启动DOMReady事件,即使脚本仍在服务器上运行。


与其他一些注释相反,</body></html>不是DOM准备就绪的良好指标,主要是因为页面可能格式错误(拼写错误或不包括这些结束标记)。在这些情况下,浏览器仍将在Quirksmode中渲染并启动DOMReady。

根据jQuery网站,$( document ).ready()只有在页面文档对象模型(DOM)准备好执行JavaScript代码后才会运行。

参考:http://learn.jquery.com/using-jquery-core/document-ready/

它在DOM层次结构完全构建并且没有更多的PHP代码可执行(因为PHP代码是在发送页面之前执行的)之后触发。

这意味着一旦客户端接收到页面,它就会立即执行。之后可能会加载其他内容,例如图像、CSS和其他Javascript。加载DOM时,

Document.ready()被激发。当所有HTML都存在时,将触发DOM ready事件。

PHP不会干扰DOM ready,因为PHP是一种服务器端编码语言。它将从服务器进行处理,服务器发送请求的页面,然后浏览器加载页面,并触发DOM ready事件。

DOM ready和窗口load之间的区别在于,加载将等待每个图像/css加载完毕。标签出现在HTML中,但没有显示图像。

基本上,我们可以说,当浏览器读取HTML关闭标记(</html>

时,DOM就绪被触发