在$(document).ready()函数中包装jquery代码有多重要?

时间:2015-06-17 14:45:47

标签: javascript jquery ruby-on-rails

我一直用jQuery开发我的前端代码已经有一段时间了,因为我在rails中实现了部分内容。通常我会使用content_for :javascript来包含一些特定于视图的代码。

我的问题是,我最终得到了很多脚本标签,因为大多数都是jquery代码,我输入了很多$(document).ready(function() {});

所以我的问题是,是否有必要将所有内容都包装在document.ready中,如果我有太多document.ready会影响性能吗?

3 个答案:

答案 0 :(得分:3)

$(document).ready()有一个目的 - 在DOM加载完成后执行一些代码,现在可以进行访问或修改。

如果您的代码位于DOM元素之前,例如在<head>标记之前或<body>部分的顶部或中间,那么在某些DOM元素之前,该代码确实首先尝试访问DOM初始化,然后它应放在$(document).ready()块中,以便在DOM准备好或者应该移动`标记之前不会执行。

如果您的代码位于<script>内的<body>标记中,该标记位于需要访问的DOM元素之后,那么您的代码不需要位于$(document).ready()块中。

或者,如果您的代码在初始化时未被调用(例如,稍后仅在其他事件时调用),或者您的代码在初始化时未访问DOM,则该代码不需要位于$(document).ready()块内

虽然您显然可以使用jQuery,但您可以阅读此答案以获取更详细的说明:pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it

拥有多个$(document).ready()块就像为一个事件注册多个回调一样。这真的没什么大不了的。每个只需要额外的几个函数调用来设置,并且在执行时是额外的回调执行。如果这是编写代码的最简洁方法,那么无论如何都要使用多个$(document).ready()块。

总结一下,在以下情况下将代码放入$(document).ready()块:

  1. 特定代码块在首次运行时需要访问DOM,代码位于脚本标记中,该脚本标记位于<body>标记结尾之前或放在某些DOM元素之前可能需要访问。
  2. 在以下情况下无需将代码放入$(document).ready()块:

    1. 在首次初始化时运行的代码部分不会访问DOM。
    2. 代码放在<script>标记中,该标记位于它引用的DOM元素之后。
    3. <script>标记标记为defer,因为它明确指示浏览器延迟此脚本标记的运行,直到解析完DOM后。
    4. 另外,请记住声明函数的位置并不重要。它只对调用函数的位置很重要。因此,您可以在$(document).ready()之外定义任意数量的函数。您只需要确保访问DOM的任何函数都不会太快调用。

答案 1 :(得分:1)

如果您的代码确实访问了您的DOM元素,但是您将其放在$(document).ready()之外,则可能会失败或产生意外行为。请参阅以下示例:

var listA = $('ul.myclass').children();
$(document).ready(function(){
    var listB = $('ul.myclass').children();
});

从上面的简单代码段开始,即使您的文档尚未完全加载或准备就绪,在加载脚本时会立即计算listA,而在文档加载并准备就绪时计算listB

listAlistB在这种情况下可能会有所不同,即使它们是从同一个DOM选择器计算出来的。

您可以初始化一些变量值或预加载一些与document.ready()之外的UI无关的值。但是,当您想要在启动时初始化UI或访问DOM时,请始终在文档完成加载(document.ready)时执行此操作。

答案 2 :(得分:1)

我同意@ jfriend00所说的一切,但也要记住,并非所有代码都需要在document.ready事件中。我的意思是你可以随时创建你的功能,只需要document.ready 执行。例如:

function manipulateDOM( el ) {
  document.getElementById(el).classList.add('myClass');
}

$(document).ready(function()){
  manipulateDOM('myEl');
});