jQuery: Tại sao lại sử dụng document.ready nếu JS bên ngoài ở cuối trang?


88

Tôi bao gồm tất cả JS của mình dưới dạng các tệp bên ngoài được tải ở cuối trang. Trong các tệp này, tôi có một số phương thức được định nghĩa như vậy, mà tôi gọi từ sự kiện sẵn sàng:

var SomeNamepsace = {};

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

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

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

Tuy nhiên, khi tôi xóa hàm ready và gọi các phương thức ngay lập tức, mọi thứ hoạt động giống nhau, nhưng thực thi nhanh hơn đáng kể — nhanh hơn gần một giây trên một tệp khá cơ bản! Vì tài liệu sẽ được tải tại thời điểm này (vì tất cả các đánh dấu đều xuất hiện trước các thẻ script), có lý do chính đáng nào để vẫn sử dụng sự kiện sẵn sàng không?


9
Câu hỏi thú vị. Đáng buồn là các câu trả lời hiện tại không thực sự trả lời câu hỏi và tôi cũng không có câu trả lời nào tốt. Có lẽ nó sẽ giúp đỡ để diễn đạt lại câu hỏi như: "được đặt văn bản Javascript vào cuối đảm bảo tập tin DOM được nạp trước khi thực hiện"
Boris Callens

Câu trả lời:


116

Câu hỏi tuyệt vời.

Có một số nhầm lẫn xung quanh toàn bộ lời khuyên "đặt tập lệnh ở cuối trang của bạn" và (các) vấn đề mà nó cố gắng giải quyết. Đối với câu hỏi này, tôi sẽ không nói về việc đặt các tập lệnh ở cuối trang có ảnh hưởng đến hiệu suất / thời gian tải hay không. Tôi sẽ chỉ nói về việc bạn có cần hay $(document).ready không nếu bạn cũng đặt các script ở cuối trang .

Tôi giả sử rằng bạn đang tham chiếu đến DOM trong các hàm đó mà bạn đang gọi ngay lập tức trong các tập lệnh của mình (bất kỳ thứ gì đơn giản như documenthoặc document.getElementById). Tôi cũng giả định rằng bạn chỉ hỏi về các tệp [tham chiếu DOM] này. IOW, tập lệnh thư viện hoặc tập lệnh mà mã tham chiếu DOM của bạn yêu cầu (như jQuery) cần được đặt trước đó trong trang.

Để trả lời câu hỏi của bạn : nếu bạn bao gồm các tập lệnh tham chiếu DOM ở cuối trang, Không, bạn không cần $(document).ready.

Giải thích : không có sự trợ giúp của "onload"các triển khai có liên quan như $(document).readyquy tắc chung là: bất kỳ mã nào tương tác với các phần tử DOM trong trang phải được đặt / đưa sâu xuống trang hơn các phần tử mà nó tham chiếu. Điều dễ dàng nhất để làm là đặt mã đó trước khi đóng </body>. Xem ở đâyở đây . Nó cũng hoạt động xung quanh lỗi "Hoạt động bị hủy bỏ" đáng sợ của IE .

Có nói rằng, điều này không có nghĩa là vô hiệu việc sử dụng $(document).ready. Tham chiếu đến một đối tượng trước khi nó được tải là [một trong những] lỗi thường gặp nhất khi bắt đầu trong DOM JavaScript (đã chứng kiến ​​nó quá nhiều lần để đếm). Đây là giải pháp của jQuery cho vấn đề và nó không yêu cầu bạn phải suy nghĩ về vị trí mà tập lệnh này sẽ được đưa vào liên quan đến các phần tử DOM mà nó tham chiếu. Đây là một chiến thắng lớn cho các nhà phát triển. Đó chỉ là một điều ít hơn họ phải suy nghĩ.

Ngoài ra, việc di chuyển tất cả các tập lệnh tham chiếu DOM xuống cuối trang thường khó hoặc không thực tế (ví dụ: bất kỳ tập lệnh nào gây ra các document.writecuộc gọi phải được giữ nguyên). Lần khác, bạn đang sử dụng một khuôn khổ hiển thị một số mẫu hoặc tạo các đoạn javascript động, trong đó tham chiếu các hàm cần được đưa vào trước js.

Cuối cùng, nó từng là "phương pháp hay nhất" để nhét tất cả mã tham chiếu DOM vào window.onload, tuy nhiên nó đã bị che khuất bởi các $(document).readytriển khai vì lý do tài liệu tốt .

Tất cả điều này trở thành $(document).readymột giải pháp cao cấp, thực tế và chung cho vấn đề tham chiếu các phần tử DOM quá sớm.


5
"nếu bạn bao gồm các tập lệnh tham chiếu DOM ở cuối trang, Không, bạn không cần $ (tài liệu) .ready." tất cả CSS được tải xuống và xử lý trước khi chạy javascript. Điều này có thể không đúng; trình duyệt có thể tải xuống các tệp bên ngoài song song.
Powerlord 17/09/09

8
không hoàn toàn chính xác, nếu bạn có defersẵn bất kỳ tài liệu script nào sẽ đảm bảo chúng thực thi trước đoạn mã sẵn sàng. xem: w3.org/TR/html5/the-end.html#the-end
Sam Saffron
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.