什么时候执行 $(document) . ready 回调?

假设我们在 $(document).ready回调中将一个 .click()处理程序附加到一个锚(<a>)标记。此处理程序将取消默认操作(在 href之后)并显示警报。

我想知道的是回调的确切执行时间,用户是否有可能点击锚(文档已经在浏览器中显示) ,但事件还没有被附加。

下面是包含锚的不同 HTML 页面,但是包含脚本的顺序不同。他们之间(如果有的话)有什么区别?不同的浏览器会有不同的表现吗?

第一页:

<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$('a').click(function() {
alert('overriding the default action');
return false;
});
});
</script>
</head>
<body>
<a href="http://www.google.com">Test</a>
</body>
</html>

第二页:

<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
</head>
<body>
<a href="http://www.google.com">Test</a>
<script type="text/javascript">
$(function() {
$('a').click(function() {
alert('overriding the default action');
return false;
});
});
</script>
</body>
</html>

第三页:

<html>
<head>
<title>Test 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<a href="http://www.google.com">Test</a>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$('a').click(function() {
alert('overriding the default action');
return false;
});
});
</script>
</body>
</html>

那么,是否有可能用户通过单击锚点被重定向到 href而从未看到警报(当然忽略禁用 javascript 的情况) ?这种情况会发生在我提供的任何示例中吗?

所有我需要的是确保 click事件处理程序已经连接到锚之前,用户有任何可能性点击这个锚。我知道我可以提供一个空的 href,然后在 javascript 中逐步增强它,但这是一个更普遍的问题。

如果 Web 服务器快速生成 HTML,但 jquery 库需要时间从远程服务器获取,那么会发生什么情况?这会影响我的计划吗?与加载 DOM 相比,包含脚本的顺序是什么?它们能同时完成吗?

9458 次浏览

你有几个不同的问题

$(文档) . ready 的确切时间 执行回调?

只要 DOM 完全加载,就会立即执行。当所有的东西(如图像)都下载完毕时,就不是这样了。Load ()将是。它(通常)在那之前,基本上是当页面自身被构建的时候。

我想知道的是什么时候 准确地执行回调

当它被点击的时候。

用户是否可以点击 在锚上(该文件已 浏览器显示) ,但事件 还没有连上。

是的,有可能。但是把它放在。给你最好的机会。只有两种方法可以做到这一点,以“更加肯定”它不会。它们实际上是在链接本身上使用‘ onclick’,并将 javascript 直接放在链接之后(而不是放在。Ready () ,所以在创建链接之后立即执行。

另外,您提供的2个代码示例的工作方式也没有什么不同。但是,在第二种情况下,不需要将代码放在。Ready () ,因为它存在于链接之后,所以它总是在创建链接之后执行。如果将其从。Ready ()它将是我上面描述的两种方法中的第一种。

此外,与其在回调中使用“ return false;”,不如使用。()和。这将允许您指定是否要防止默认操作或阻止事件冒泡,或者两者兼而有之。

这取决于很多事情。例如,如果您有块编码,那么用户可能会得到一个块,但是因为文档还没有准备好,所以侦听器将不会被附加。

JQuery 就绪事件是兼容 W3C 的浏览器中的 DOM 内容加载事件(在 HTML5规范中标准化) ,以及其他浏览器中的一些 选择事件(如 IE 中的 readystate)。

DOMContentLoaded (MDC)

触发页的 Document 对象 当文档解析为 完成。到这个事件的时候 触发时,页面的 DOM 已准备就绪。

因为这是在呈现之前发生的,所以这是一个可靠的假设,即在此事件之后执行的回调将能够防止用户在尚未准备好的页面上进行交互。

但正如 Peter Michaux 在 他的文章中指出的,浏览器实现这个事件 “在四大浏览器中,不可能有一种强大的早期活跃技术。”的方式不同

所以我会说你的 不能100% 相信对 jQuery 就绪事件,但是 大多数时候它会工作就很好。

当然,可以“欺骗”警告(即使启用了 Javascript)。尝试在 url 字段中拖动链接,您将看到它将在没有警告的情况下执行。如果链接正在触发 delete 操作,那么这个问题尤其严重。

关于文件。准备回调-我也有这样的问题。听我解释。我们正在做一个项目,其中所有的表单都显示在弹出窗口(jQuery 窗口)中。因此,当弹出窗口关闭时(现在)页面会被重新加载,而且我有时会被重定向到另一个屏幕而不是打开一个新的弹出窗口。

完全同意 user384915关于将 javascript 直接放在 onClick 事件上,甚至更好的方法是 href 标记。

示例3机会最大,用户可以单击链接而不需要处理程序附加自己。因为你正在加载 jQuery 库 之后链接是呈现的,如果谷歌的服务器有点慢(或者 DNS 查找需要一秒钟左右) ,或者用户电脑处理 jQuery 的速度很慢,当用户试图点击它时,链接将不会有它的点击处理程序。

另一种可能发生这种情况的情况是,如果你有一个非常大或慢加载页面,这个链接在顶部。那么,当 DOM 的某些部分可见时,DOM 可能还没有完全准备好。如果遇到这样的问题,最安全的东西要做的是:

  1. head中加载 jQuery (示例1或2)
  2. <a>元素之后立即附加 click 事件,但不要在 DOMReady 回调中附加。这样,它将被立即调用,而不会等待文档的其余部分。

一旦呈现了一个元素,就可以从 DOM 中获取它,随后 jQuery 就可以访问它:

<a href="http://www.google.com">Test</a>
<script type="text/javascript>
// No (document).ready is needed. The element is availible
$('a').click(function() {
alert('overriding the default action');
return false;
});
</script>

此外, 基于 user384915的注释,如果操作完全依赖于 JavaScript,那么甚至不要将其作为 HTML 的一部分呈现,在 jQuery 准备好之后添加它:

<script type="text/javascript">
jQuery(function($){
$("<a />", {
style: "cursor: pointer",
click: function() {
alert('overriding the default action');
return false;
},
text: "Test"
}).prependTo("body");
});
</script>

第三个示例提供了在没有附加覆盖处理程序的情况下用户单击的最大机会。浏览器通常先下载并解析每个 <script>,然后再转到下一个。您从外部源(Google)获取 jQuery ——尽管它可能可靠,但可能不可用或加载速度缓慢。在文档 <body>的末尾有两个 <script>块,因此在处理最后两个脚本时,页面的前两个区域可能已经被下载并呈现到屏幕上。虽然这种方法主张向用户提供响应性页面加载体验,但是他们可以在这个不确定的时期单击,当然还没有附加覆盖处理程序。

有一篇关于脚本和加载顺序 给你的有趣 YUIblog 文章。

在 YUI 中,有方法 onContentReady()onAvailable()。不幸的是,在 jQuery 中没有类似的代码。然而,有一个插件的灵感来自他们:

Http://www.thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin/

这应该允许您在 DOM 完全加载之前将事件绑定到锚点。