7

这个问题的评论让我想到了一些事情。函数究竟什么时候$(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 开发检查器中所见)。查看页面的源代码显示它在中间,不过我在其中附和了它。

4

5 回答 5

6

ready一旦 jQuery 确定 DOM 是可访问的,jQuery 的文档事件就会触发。确切的机制取决于浏览器。

看看相关的源代码

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

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

  • 尝试并附加到onreadystatechange文档的事件。这不是万无一失的,并且会比DOMContentLoaded本来的晚,但它非常好。
  • 回退到对象的load事件window。这通常比 DOM 可用晚得多,但它是确保事件最终始终触发的最后一道防故障措施。
  • 最坏的情况:不断轮询 DOM,直到它可以访问为止。

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

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

于 2013-07-08T18:18:55.567 回答
3

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

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

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

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


与其他一些评论相反,</body></html>并不是 DOM 准备就绪的良好指标,主要是因为页面可能格式错误(有拼写错误或不包含这些结束标记)。在这些情况下,浏览器仍会以 Quirksmode 呈现并触发 DOMReady。

于 2013-07-08T18:22:26.930 回答
0

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

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

于 2013-07-08T18:10:01.613 回答
0

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

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

于 2013-07-08T18:10:53.850 回答
0

Document.ready()当 DOM 完成加载时触发。当所有 HTML 都存在时,ready将触发 DOM 事件。

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

readyDOM和 window之间的区别在于loadload 将等到每个图像/css 都加载完毕。标记存在于 HTML 中,但未显示图像。

基本上,我们可以说当浏览器读取 HTML 结束标记 ( </html>)时触发 DOM 就绪

于 2013-07-08T18:11:13.870 回答