window.onload vs document.onload


711

Cái nào được hỗ trợ rộng rãi hơn: window.onloadhay document.onload?


2
Tài liệu MDN giải thích những windowsự kiện này : onloadDOMContentLoaded. Ví dụ sử dụng:, window.addEventListener('DOMContentLoaded', callback). Tính đến giữa năm 2019, tương thích với tất cả các trình duyệt chính. ----- developer.mozilla.org/en-US/docs/Web/API/Window/ Khăn ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks

Đối với tôi thậm chí vẫn còn, trong Firefox 75,0 ngày hôm nay, window.onloaddocument.onloadkhác nhau từ mỗi khác! window.onloaddường như diễn ra sau đó và có tải hơn một chút so với document.onload! (Một số thứ đang hoạt động với cửa sổ không hoạt động với tài liệu! Điều đó cũng đúng với tài liệu.onreadstatechange 'hoàn thành'!)
Andrew

Câu trả lời:


723

Khi nào họ bắn?

window.onload

  • Theo mặc định, nó được kích hoạt khi toàn bộ trang tải, bao gồm nội dung của nó (hình ảnh, CSS, tập lệnh, v.v.).

Trong một số trình duyệt, giờ đây nó sẽ đảm nhận vai trò document.onloadvà kích hoạt khi DOM cũng sẵn sàng.

document.onload

  • Nó được gọi khi DOM sẵn sàng có thể trước hình ảnh và nội dung bên ngoài khác được tải.

Họ được hỗ trợ tốt như thế nào?

window.onloaddường như được hỗ trợ rộng rãi nhất. Trong thực tế, một số trình duyệt hiện đại nhất có nghĩa được thay thế document.onloadbằng window.onload.

Các vấn đề hỗ trợ trình duyệt rất có thể là lý do khiến nhiều người bắt đầu sử dụng các thư viện như jQuery để xử lý việc kiểm tra tài liệu đã sẵn sàng, như vậy:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

Vì mục đích lịch sử. window.onloadvs body.onload:

Một câu hỏi tương tự đã được hỏi về tiền mã hóa một thời gian trước về việc sử dụng window.onloadhơn body.onload. Kết quả có vẻ là bạn nên sử dụng window.onloadvì tốt nhất là tách cấu trúc của bạn khỏi hành động.


25
Trên thực tế, tuyên bố đó dường như được hướng vào một sự lựa chọn giữa window.onload<body onload="">hoàn toàn khác nhau (và "cấu trúc riêng biệt từ hành động" có ý nghĩa hơn rất nhiều trong bối cảnh này). Không phải là câu trả lời là sai, nhưng cơ sở của nó là.
Thor84no

2
Câu nói đó thật kinh khủng về mặt ngữ pháp ... không nên giúp đỡ chỉnh sửa (đánh dấu)?
Kheldar

@ Thor84no Cuối cùng tôi đã tìm thấy thời gian để xem xét lại cái này. Tôi đã thực hiện một vài cải tiến.
Josh Mein

@Kainedar Tôi quyết định diễn giải đoạn trích vì nó khá thô.
Josh Mein

@JoshMein Có nghĩa là nó document.onloadtương đương với JS của jQuery document.ready?
john cj

276

Ý tưởng chung là window.onload kích hoạt khi cửa sổ của tài liệu sẵn sàng để trình bàydocument.onload kích hoạt khi cây DOM (được xây dựng từ mã đánh dấu trong tài liệu) được hoàn thành .

Lý tưởng nhất là đăng ký các sự kiện của cây DOM , cho phép các thao tác ngoài màn hình thông qua Javascript, phát sinh gần như không tải CPU . Ngược lại, window.onloadcó thể mất một lúc để kích hoạt , khi nhiều tài nguyên bên ngoài chưa được yêu cầu, phân tích cú pháp và tải.

► Kịch bản thử nghiệm:

Để quan sát sự khác biệt và cách trình duyệt lựa chọn của bạn thực hiện các trình xử lý sự kiện đã nói ở trên , chỉ cần chèn mã sau vào trong <body>thẻ - tài liệu của bạn .

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Result:

Dưới đây là hành vi kết quả, có thể quan sát được đối với Chrome v20 (và có lẽ là hầu hết các trình duyệt hiện tại).

  • Không có document.onloadsự kiện.
  • onloadbắn hai lần khi được khai báo bên trong <body>, một lần khi được khai báo bên trong <head>(khi đó sự kiện sẽ đóng vai trò document.onload).
  • đếm và hành động phụ thuộc vào trạng thái của bộ đếm cho phép mô phỏng cả hai hành vi sự kiện.
  • Hoặc khai báo window.onloadtrình xử lý sự kiện trong giới hạn của <head>phần tử HTML .

► Dự án mẫu:

Mã ở trên được lấy từ cơ sở mã của dự án này ( index.htmlkeyboarder.js).


Để biết danh sách các trình xử lý sự kiện của đối tượng cửa sổ , vui lòng tham khảo tài liệu MDN.


142

Thêm người nghe sự kiện

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1 vani JavaScript

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


Chúc may mắn.


14
"Sự kiện DOMContentLoaded được kích hoạt khi tài liệu HTML ban đầu đã được tải và phân tích cú pháp hoàn toàn, không cần chờ biểu định kiểu, hình ảnh và khung con để tải xong." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Vì vậy, bạn dường như không chính xác về mọi thứ đang được tải tại sự kiện này.
ProfK

2
@ProfK, cảm ơn bạn đã phản hồi. Bạn có thể thử window.addEventListener('load', function() {...}). Tôi cũng đã cập nhật câu trả lời của mình.
Akash

4
Điều tôi thích về câu trả lời này là nó mang lại một giải pháp javascript đơn giản. Bạn sẽ nghĩ rằng hầu hết mọi người nghĩ rằng jQuery được tích hợp vào tất cả các trình duyệt, với mức độ thường xuyên được đưa ra như là câu trả lời duy nhất.
Dave Land

Vấn đề kép khi jquery chết tiệt mất quá nhiều thời gian để tải và bạn nhận được $ không tìm thấy. Tôi cho rằng các giải pháp loại $ (cửa sổ) đã sẵn sàng KHÔNG BAO GIỜ được tin cậy để làm việc.
Shayne

1
Tôi đã thử cả hai ngày nay chrome. Nó không chờ css và phông chữ.
MovAX13h

78

Theo phân tích tài liệu HTML - Kết thúc ,

  1. Trình duyệt phân tích nguồn HTML và chạy các tập lệnh bị trì hoãn.

  2. A DOMContentLoadedđược gửi vào lúc documenttất cả các HTML đã được phân tích cú pháp và đã chạy. Các sự kiện bong bóng đến window.

  3. Trình duyệt tải tài nguyên (như hình ảnh) làm trì hoãn sự kiện tải.

  4. Một loadsự kiện được gửi tại window.

Do đó, thứ tự thực hiện sẽ là

  1. DOMContentLoadedngười nghe sự kiện windowtrong giai đoạn chụp
  2. DOMContentLoaded người nghe sự kiện của document
  3. DOMContentLoadedngười nghe sự kiện windowtrong giai đoạn bong bóng
  4. loadngười nghe sự kiện (bao gồm cả onloadxử lý sự kiện) củawindow

Một loadngười nghe sự kiện bong bóng (bao gồm cả onloadxử lý sự kiện) documentkhông bao giờ được gọi. Chỉ loadngười nghe nắm bắt có thể được gọi, nhưng do tải tài nguyên phụ như biểu định kiểu, không phải do tải của tài liệu.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};


Tôi đã chạy đoạn trích của bạn và document - load - capturethực sự xảy ra, điều này trái ngược với những gì tôi đang mong đợi trong tìm kiếm của mình về lý do tại sao tải tài liệu không xảy ra với tôi. Kỳ lạ thay, nó không nhất quán. Đôi khi nó xuất hiện, đôi khi không, đôi khi nó xuất hiện hai lần - nhưng không bao giờ document - load - bubblexảy ra. Tôi sẽ đề nghị không sử dụng document load.
lỗi

@erroric Điểm tốt. Tôi đã không nghĩ rằng một loadsự kiện được gửi đi từ các nguồn lực bên ngoài. Sự kiện đó không nổi bong bóng nên thường không được phát hiện trên tài liệu, nhưng nó sẽ ở trong giai đoạn chụp. Các mục này đề cập đến tải của các yếu tố <style><script>. Tôi nghĩ Edge phù hợp để hiển thị chúng và Firefox và Chrome đã sai.
Oriol

Cảm ơn Oriol, useCapturetùy chọn đã dạy tôi một cái gì đó mới.
Paul Watson

Cảm ơn bạn đã tóm tắt luồng phân tích và kết xuất từ ​​w3. Tôi chỉ tự hỏi sau khi bước 4 một khi sự kiện 'tải' được kích hoạt, điều gì khác có thể xảy ra? Tôi nhận thấy trên trình duyệt của mình rằng đôi khi vẫn còn một số đối tượng được tìm nạp sau khi sự kiện tải được kích hoạt mặc dù tôi hoàn toàn không chạm vào hoặc tương tác với trang. Bạn có biết những đối tượng đó được gọi là gì không? 'Các đối tượng kết xuất không chặn?
Sydfwefwqg3

12

Trong Chrome, window.onload khác với <body onload="">, trong khi chúng giống nhau ở cả Firefox (phiên bản 35.0) và IE (phiên bản 11).

Bạn có thể khám phá điều đó bằng đoạn trích sau:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

Và bạn sẽ thấy cả "cửa sổ được tải" (trước hết là) và "tải trọng cơ thể" trong bảng điều khiển Chrome. Tuy nhiên, bạn sẽ chỉ thấy "body onload" trong Firefox và IE. Nếu bạn chạy " window.onload.toString()" trong bảng điều khiển của IE & FF, bạn sẽ thấy:

"hàm onload (sự kiện) {bodyOnloadHandler ()}"

có nghĩa là phép gán "window.onload = function (e) ..." bị ghi đè.


6

window.onloadonunloadlà các phím tắt đến document.body.onloaddocument.body.onunload

document.onloadonloadtrình xử lý trên tất cả các thẻ html dường như được bảo lưu tuy nhiên không bao giờ được kích hoạt

' onload' trong tài liệu -> đúng


5

window.onload tuy nhiên chúng thường giống nhau. Tương tự body.onload trở thành window.onload trong IE.


1

Tuy nhiên, Window.onload là tiêu chuẩn - trình duyệt web trong PS3 (dựa trên Netfront) không hỗ trợ đối tượng cửa sổ, vì vậy bạn không thể sử dụng nó ở đó.


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.