jQuery document.ready

9

我对jQuery中的document.ready有些困惑。

在何时应该在$(document).ready()内定义javascript函数?在何时不需要?

是否将所有javascript代码都放在$(document).ready()内就足够安全了?

如果不这样做会发生什么?

例如,我使用常规的jQuery选择器,在单击元素时执行某些操作。如果不将它们包装在document.ready内,会有什么危害?

只会在页面加载前瞬间单击元素才会导致问题吗?或者会有其他问题?

5个回答

8
当您需要在全局范围内访问函数时(这可能表明应用程序设计不良),则必须在ready处理程序之外定义它们。
将所有javascript代码放在$(document).ready()中是否足够安全?请参见上文。
如果您不这样做会发生什么?这取决于您的JavaScript代码在做什么以及其位置。在最坏的情况下,您将因为尝试在DOM元素存在之前访问它们而获得运行时错误。如果您的代码位于中,并且不仅定义函数而且已经尝试访问DOM元素,则会发生这种情况。
例如,我使用通常的jQuery选择器,在单击某些内容时执行操作。如果您没有使用document.ready包装它们,会有什么危害?

本质上没有“伤害”。如果脚本位于中,则无法正常工作,因为DOM元素尚不存在。这意味着,jQuery无法找到并绑定处理程序。
但是,如果将脚本放置在关闭的标记之前,那么DOM元素将存在。


为了安全起见,无论何时想要访问DOM元素,请将这些调用放置在ready事件处理程序中或仅在DOM加载后调用的函数中。
正如jQuery教程(您应该阅读它)已经说明的那样:

As almost everything we do when using jQuery reads or manipulates the document object model (DOM), we need to make sure that we start adding events etc. as soon as the DOM is ready.

To do this, we register a ready event for the document.

$(document).ready(function() {
    // do stuff when DOM is ready
});

提供一个更完整的示例:

<html>
    <head>
        <!-- Assuming jQuery is loaded -->
        <script>

            function foo() {
                // OK - because it is inside a function which is called
                // at some time after the DOM was loaded
                alert($('#answer').html());
            }

            $(function() {
                // OK - because this is executed once the DOM is loaded
                $('button').click(foo);
            });

            // OK - no DOM access/manipulation
            alert('Just a random alert ' + Math.random());

            // NOT OK - the element with ID `foo` does not exist yet
            $('#answer').html('42');

        </script>
    </head>
    <body>
        <div id="question">The answer to life, the universe and everything</div>
        <div id="answer"></div>
        <button>Show the answer</button>

        <script>
           // OK - the element with ID `foo` does exist
           $('#answer').html('42');
        </script>
    </body>
</html>

除了作用域之外,函数foo()被排除在document.ready之外还有其他原因吗?这只是惯例还是有像性能这样的原因?当我使用全局作用域时,我使用“window.foo = function(){};”样式来使用显式作用域定位。这样做会不会稍微推迟声明变量的JS执行时间,从而允许浏览器在声明函数之前继续加载HTML,并因此更快地呈现出可见的内容(可以忽略不计)? - Joel Peltonen
1
@Nenotlep:我认为将函数移动到ready处理程序内部可能更快,正如您提到的原因一样。这就是为什么将所有脚本放在body末尾也是一个好习惯。但是,如果性能影响可以忽略不计,那么它也取决于个人喜好。这个具体的例子只是为了演示什么必须进入ready处理程序,什么不必要。 - Felix Kling

6

document.ready处理程序在浏览器加载完DOM并准备好进行操作时触发。

是否应该使用它取决于您放置自定义脚本的位置。如果您将它们放在文档末尾,紧接着关闭的</body>标记之前,您不需要使用document.ready,因为在您的脚本执行时,DOM已经被加载,您可以操作它。

另一方面,如果您将脚本放在文档的<head>部分中,您应该使用document.ready确保DOM在尝试修改它或将事件处理程序附加到各个元素之前完全加载。如果您不这样做,并且尝试将例如.click事件处理程序附加到按钮,则此事件将永远不会触发,因为在您的脚本运行时,您用于查找按钮的jQuery选择器未返回任何元素,您没有成功地附加处理程序。


谢谢。我想知道这是否是我遇到奇怪行为的原因。 - Dave31415

4

当您需要等待DOM加载后再执行代码时,请将代码放在$(document).ready中。如果代码不需要先等待DOM存在才能运行,则可以将其放在$(document).ready之外。

顺便说一下,$(function() { })是$(document).ready();的简写。

$(function() {
   //stuff here will wait for the DOM to load
   $('#something').text('foo'); //should be okay
});

//stuff here will execute immediately.
/* this will likely break */
$('#something').text('weee!');

其实,它还可以更有趣。由于这个结构,你可以在 $() 中传递任何函数引用,并且当文档准备就绪时它会自动启动:$(myfunction)。由于少了一个闭包,因此可以节省一些内存。 - Ben Lesh
你也可以用另一种方式实现相同的效果:$(document).ready(myfunction)$(myfunction) 是等价的。 - Ben Lesh

1
如果您的脚本位于文档末尾,则不需要使用document.ready。
例如:有一个按钮,点击它时,您需要显示一个警报。 您可以在document.ready中将单击事件绑定到按钮。 您可以在文档末尾或标记中加载元素后编写jquery脚本。
在document.ready事件中编写所有内容会使您的页面变得缓慢。

0
如果你在href属性中调用js函数,那么在ready()中不添加事件处理程序是没有问题的。但如果你是使用jQuery添加它们,那么你必须确保这些处理程序所引用的对象已被加载,并且这段代码必须在文档被视为ready()之后再执行。这并不意味着它们必须在ready()调用中,你可以在ready()内部调用的函数中调用它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接