何时执行$(document).readycallback?
假设我们将.click()
处理程序附加到$(document).ready
callback中的一个锚( <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可能没有完全准备好。 如果你遇到这样的问题, 最安全的做法是:
- 在
head
加载jQuery(示例1或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标签上。