JQuery: 如果外部 JS 位于页面底部,为什么要使用 document.ready?

我将所有的 JS 作为外部文件包含在页面的最底部。在这些文件中,我有几个这样定义的方法,我从 ready 事件调用它们:

var SomeNamepsace = {};


SomeNamepsace.firstMethod = function () {
// do something
};


SomeNamepsace.secondMethod = function () {
// do something else
};


$(document).ready(function () {
SomeNamepsace.firstMethod();
SomeNamepsace.secondMethod();
});

但是,当我删除 ready 函数并直接调用这些方法时,所有操作都一样,但是执行速度要快得多ーー在一个相当基本的文件上要快几乎整整一秒钟!由于文档应该在这个时候加载(因为所有标记都在 script 标记之前) ,那么还有什么理由继续使用 ready 事件呢?

28035 次浏览

Great question.

There is some confusion around the whole "put scripts at the bottom of your page" advice and what problem(s) it attempts to solve. For this question I am not going to talk about whether putting scripts at the bottom of the page affects performance/loadtimes or not. I am only going to talk about whether you need $(document).ready if you also put scripts at the bottom of the page.

I'm assuming you are referencing the DOM in those functions you are immediately invoking in your scripts (anything as simple as document or document.getElementById). I'm also assuming you are asking only about these [DOM-referencing] files. IOW, library scripts or scripts that your DOM-referencing code requires (like jQuery) need to be placed earlier in the page.

To answer your question: if you include your DOM-referencing scripts at the bottom of the page, No, you do not need $(document).ready.

Explanation: without the aid of "onload"-related implementations like $(document).ready the rule of thumb is: any code that interacts with DOM elements within the page should to be placed/included further down the page than the elements it references. The easiest thing to do is to place that code before the closing </body>. See here and here. It also works around IE's dreaded "Operation aborted" error.

Having said that, this by no means invalidates the use of $(document).ready. Referencing an object before it has been loaded is [one of] the most common mistakes made when beginning in DOM JavaScript (witnessed it too many times to count). It is jQuery's solution to the problem, and it doesn't require you to have to think about where this script will be included relative to the DOM elements it references. This is a huge win for developers. It's just one less thing they have to think about.

Also, it's often difficult or impractical to move all DOM-referencing scripts to the bottom of the page (for example any script that issues document.write calls have to stay put). Other times, you are using a framework that renders some template or creates pieces of dynamic javascript, within which references functions that need to be included before the js.

Finally, it used to be "best practice" to jam all DOM-referencing code into window.onload, however it has been eclipsed by $(document).ready implementations for well document reasons.

All this adds up to $(document).ready as a far superior, practical and general solution to the problem of referencing DOM elements too early.