在大多数教程中,关于如何执行jquery脚本,有两种方法:
- 用
window.onload
钩。 - 具有
$(document).ready(function(){...})
事件(可以缩写为$(function(){...})
)
而且我发现当我省略所有这些时,它甚至可以工作,只需将代码放在<script></script>
遮挡中即可达到相同的目的。就像这样:
<html>
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
<body>
<button id="btn" name="test" value="clickme">clickme</button>
</body>
<script>
//$(document).ready( function(){
// $('#btn').on("click", function(e){
// alert("hi")
// }
//)})
$('#btn').on('click', function(e){
alert('hi')
})
</script>
</html>
如您所见,未注释的代码(省略了所有document.ready
员工或window.onload
)和注释的代码都可以按预期向我发出警报。
所以我的问题是,在这种情况下(绑定事件),因为我可以编写更优雅的代码作为未注释的代码片段。我为什么要像大多数教程中所说的那样费心编写代码(如上面的注释样式)?
中没有 defer
或 async
属性的<script>
标记将按照 HTML 文档自上而下的解析顺序执行。 这意味着文档顶部附近的脚本将在文档的其余部分被解析之前执行,从而在文档可用之前执行。 这使得脚本的位置或脚本的执行时间在许多情况下都很重要。
在控制此执行计时时,执行启动脚本至少有五个选择:
您可以将脚本放在
<head>
部分或<body>
部分的顶部,并在加载时执行它。 这样做的缺点是 DOM 尚未加载,因此您无法对页面中的元素进行操作。您可以在
</body>
标记之前插入脚本,所有 DOM 都将加载,并且您的脚本将能够访问所有内容。您可以将脚本插入到所需的任何位置(包括在
<head>
标记中),并使用$(document).ready(fn)
在 DOM 准备就绪之前不执行fn
。 在内部,jQuery 侦听DOMContentLoaded
事件,当它触发时,它会执行任何.ready()
处理程序。您可以将脚本插入到所需的任何位置(包括在
<head>
标记中),并使用window.onload(fn)
在 DOM 准备就绪且所有外部资源(如图像)已加载之前不执行fn
。 注意,你也可以使用 jQuery 版本$(window).load(fn)
。您可以使用脚本标记上的
async
或defer
属性来强制脚本标记异步加载,稍后再加载。 这将创建脚本执行的不确定时间(尽管总是比只是内联时晚),因此您可能需要一些特定的控件,例如$(document).ready()
在脚本执行之前知道 DOM 是安全的。 您可以看到这些其他问题/答案脚本标签 - 异步和延迟和加载和执行脚本顺序,以获取有关异步和延迟属性操作的更多详细信息。
因此,如果您小心地将脚本标签放在正确的位置,或者启动脚本不尝试访问 DOM 元素,则无需使用 $(document).ready(fn)
或 window.onload(fn)
。
但是,如果您不能完全控制脚本的放置位置并且需要访问 DOM 元素,或者您希望脚本能够放置在任何地方并且仍然让它做正确的事情,或者如果您只想将所有脚本都放在 <head>
标记中,那么您将需要延迟脚本的执行,直到 DOM 准备就绪并且$(document).ready(fn)
或window.onload(fn)
将使它变得容易做到。
嗯,这两者并不完全相同。内联Javascript在遇到DOM时立即执行,因为DOM是自上而下的。但是,您提到的钩子是在 DOM 加载/准备就绪后执行的。所以是的,除了组织之外,如果你确定你的JS只依赖于在内联之前加载的DOM部分 - 你很好。否则你肯定需要钩子。
根据 jQuery 文档:
.ready( 处理程序 )
描述:指定 DOM 完全加载时要执行的函数。
document.ready
表示浏览器已经解析了所有 DOM 元素。有一种情况是,如果你有一个包含大量元素的长<body>
标签,DOM Element 对象不是由浏览器完全创建的,它也开始解析你的 JavaScript。此时,您将无法从 DOM 树中查询#btn
元素,因此事件侦听器无法附加到该元素。
为了回答你的问题,你没有发现添加和省略$(document).ready(function(){});
之间有任何区别的原因是因为你在标签结束之前保留了它html
。
- 您的代码是从上到下解析的。
- 当它到达您的脚本时,DOM 已准备就绪。因此
$(document).ready
会开火。 - 但由于脚本位于底部,因此您确定 DOM 已准备就绪。在这种情况下,
$(document).ready
没有区别。
要查看差异,请将脚本标记移动到顶部<head>
部分。然后,为了确保您的脚本正常工作,您需要将其包含在 $(document).ready
之间。否则,您将click
处理程序添加到不存在的按钮,这将不起作用。
至于window.onload
和$(document).ready
的区别:
-
加载所有内容后
window.onload
触发。这意味着当它被触发,DOM 已准备就绪,所有图像和其他图像也已准备就绪资源已准备就绪。 -
另一方面,
$(document).ready
在加载 DOM 后触发。这是在所有映像和其他资源下载并准备就绪之前。因此,这可以确保您的脚本正常工作,并且触发速度也比使用window.onload
更快。
window.onload
文档
$(document).ready
文档