何时执行$(document).readycallback?

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

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

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

第1页:

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

第2页:

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

第3页:

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

所以有可能是一个用户通过点击锚点而被redirect到href并且从来没有看到警报(当然忽略javascript的情况下)? 这可能发生在我提供的任何例子吗?

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

如果Web服务器快速生成HTML,但是jQuery库需要时间从远端服务器获取,会发生什么情况? 这会影响我的情况吗? 与加载DOM相比,包含脚本的顺序是什么? 他们可以并行吗?

示例3 将具有用户能够点击链接而没有附接自身的处理程序的最高可能性 。 由于在链接呈现之后 ,您正在加载jQuery库,如果Google的服务器有点慢(或者DNS查找需要一秒左右),或者用户计算机处理jQuery的速度很慢,那么链接将不会有其点击处理程序当用户尝试点击它时附加。

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

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

一旦元素被渲染,就可以从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> 

另外,build立在user384915的评论上,如果action完全依赖于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> 

这里有几个不同的问题

何时执行$(document).readycallback?

DOM完全加载后立即执行。 不是当一切(如图像)完成下载如.load()将是。 这是(一般)之前,基本上是当它自己build立的页面。

我想知道的是callback执行的时间

当它被点击。

用户是否可以点击锚点(文档已在浏览器中显示),但该事件尚未附加。

对的,这是可能的。 但是把它放在.ready()里给你最好的机会。 只有两种方法可以做到“更确定”,而不是。 这些实际上是在自己的链接上使用“onclick”,并将javascript直接放在链接之后(而不是在.ready()),以便在链接创build后立即执行。

而且,你提供的2个代码样本的工作方式也没有区别。 然而,在第二个中,你不需要把代码放在.ready()中,因为它存在于链接之后,它总是在链接创build之后执行。 如果你从.ready()中删除它,它将是我上面描述的两种方法中的第一种。

另外,不要把“返回错误” 在你的callback函数中,最好使用.preventDefault()和.stopPropagation(),这样可以让你指定是否要防止默认动作或者停止冒泡事件。

这取决于很多事情。 如果你有分块编码,例如用户可能会得到一个块,但是由于文档尚未准备好,监听器将不会被连接。

jQuery就绪事件是符合W3C标准的浏览器中的DOMContentLoaded事件(在HTML5规范中标准化),以及其他一些替代方法 (如IE中的readystate)。

DOMContentLoaded(MDC)

文档parsing完成时,在页面的Document对象上触发。 当这个事件触发时,页面的DOM就绪了。

因为这发生在渲染之前,所以这个事件之后执行的callback将能够阻止用户在未准备好的页面上进行交互。

但正如Peter Michaux在他的文章中指出浏览器如何实现这一事件的差异, “在四大浏览器中,早期活跃的强大技术是不可能的”。

所以我会说,你不能100%的jQuery准备事件,但大部分时间,它会工作得很好。

在YUI中,有onContentReady()onAvailable() 。 不幸的是,没有相当于jQuery的。 不过有一个插件是受他们启发的:

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

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

您的第三个示例提供了最大的机会,用户在没有附加覆盖处理程序的情况下进行单击。 浏览器通常下载并parsing每个<script>然后再转到下一个。 你从外部来源(谷歌)的jQuery拉 – 虽然可能可靠,可能不可用或缓慢加载。 在文档<body>的最后有两个<script>块,因此在处理最后两个脚本时,页面的以前区域可能已经被下载并渲染到屏幕。 虽然这种方法主张向用户提供响应式的页面加载体验,但是在这个不确定的时期,他们可以点击,当然,覆盖处理程序还没有被附加。

这里有一个关于脚本和加载顺序的有趣的YUI博客文章。

肯定可以“作弊”警告警告(即使Javascript已启用)。 尝试拖动url字段中的链接,你会发现它将被执行没有这个警告。 如果链接正在触发删除操作,则这尤其成问题。

关于document.readycallback – 我也有这样的问题。 让我解释。 我们正在做一个项目,所有的窗体都在popup窗口中显示(jQuery窗口)。 所以当popup窗口closures(现在)页面被重新加载,我有情况下,当我redirect到另一个屏幕,而不是打开一个新的popup窗口。

完全同意user384915关于将javascript直接放在onClick事件上,或者甚至更好的放在href标签上。