window.onload vs <body onload =


227

Chính xác thì sự khác biệt giữa window.onloadsự kiện và onloadsự kiện của bodythẻ là gì? Khi nào tôi nên sử dụng cái nào và làm thế nào để thực hiện chính xác?


2
bạn nên sử dụng "để bao quanh giá trị thuộc tính
Sven Larson

Câu trả lời:


218

window.onload = myOnloadFunc<body onload="myOnloadFunc();">là những cách khác nhau để sử dụng cùng một sự kiện . Việc sử dụng window.onloadít gây khó chịu hơn - nó đưa JavaScript của bạn ra khỏi HTML.

Tất cả các thư viện JavaScript phổ biến, Prototype, ExtJS, Dojo, JQuery, YUI, v.v. đều cung cấp các hàm bao đẹp xung quanh các sự kiện xảy ra khi tài liệu được tải. Bạn có thể lắng nghe cửa sổ sự kiện onLoad và phản ứng với điều đó, nhưng onLoad không được kích hoạt cho đến khi tất cả các tài nguyên đã được tải xuống, vì vậy trình xử lý sự kiện của bạn sẽ không được thực thi cho đến khi hình ảnh lớn cuối cùng được tải xuống. Trong một số trường hợp, đó chính xác là những gì bạn muốn, trong những trường hợp khác, bạn có thể thấy rằng việc lắng nghe khi DOM sẵn sàng là phù hợp hơn - sự kiện này tương tự như onLoad nhưng kích hoạt mà không cần chờ hình ảnh, v.v. để tải xuống.


57
Cần lưu ý, tuy nhiên, có một sự khác biệt. Sự kiện onload nội tuyến sẽ gọi myOnloadFunc()trong bối cảnh toàn cầu ( thissẽ tham khảo window). Đặt nó thông qua javascript sẽ làm cho nó thực thi trong ngữ cảnh của phần tử ( thistham chiếu đến phần tử mà sự kiện được kích hoạt). Trong trường hợp cụ thể này, nó sẽ không tạo ra sự khác biệt, nhưng nó sẽ với các yếu tố khác.
mowwwalker

1
@Walkerneo: Đúng, đáng chú ý. Tất nhiên, sử dụng thư viện JS, người ta có thể ghi đè lên đối tượng thistham chiếu nếu muốn.
Richard Turner

@RichardTurner Bạn không cần sử dụng thư viện để thay đổi liên kết ngữ cảnh. Một cuộc gọi .bind () đơn giản thực hiện điều đó
Kloar

@Kloar bạn có thể những ngày này, vâng, nhưng bạn cần MSIE9 +. Trên MSIE cũ, phổ biến hơn nhiều khi tôi trả lời, bạn sẽ cần một polyfill.
Richard Turner

33

Không có sự khác biệt, nhưng bạn cũng không nên sử dụng.

Trong nhiều trình duyệt, window.onloadsự kiện không được kích hoạt cho đến khi tất cả các hình ảnh được tải, đó không phải là điều bạn muốn. Các trình duyệt dựa trên tiêu chuẩn có một sự kiện được gọi là DOMContentLoadedsẽ kích hoạt trước đó, nhưng nó không được IE hỗ trợ (tại thời điểm viết câu trả lời này). Tôi khuyên bạn nên sử dụng thư viện javascript hỗ trợ tính năng DOMContentLoaded trên trình duyệt chéo hoặc tìm một chức năng được viết tốt mà bạn có thể sử dụng. jQuery $(document).ready(), là một ví dụ tốt.


53
Câu hỏi từ tương lai ... Nếu không có jquery thì sao?
Sid

54
Câu hỏi từ hiện tại .. Điều gì sẽ xảy ra nếu jQuery quá mức cần thiết cho dự án? (Không gõ jQuery, hãy tự mình sử dụng. Đôi khi chỉ muốn một tính năng ra khỏi thư viện ..)
Bradmage

14
Khi bạn nói "không được IE hỗ trợ" thì đó có phải là sự thật phổ quát hay chỉ đúng với các phiên bản cụ thể của IE? Vì rất nhiều thứ đã thay đổi trong thế giới trình duyệt kể từ khi bạn viết câu trả lời này, có lẽ đã đến lúc cập nhật câu trả lời này?
Bryan Oakley

8
DOMContentLoaded hiện được IE9 hỗ trợ trở lên: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam

6
Báo cáo từ tương lai, DOMContentLoaded hiện được hỗ trợ bởi tất cả các trình duyệt chính: caniuse.com/#feat=domcontentloaded
Jose Gómez

21

window.onloadCó thể làm việc mà không cần cơ thể. Tạo trang chỉ với các thẻ script và mở nó trong trình duyệt. Trang này không chứa bất kỳ nội dung nào, nhưng nó vẫn hoạt động ..

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>

6
HTML không có thẻ body là không hợp lệ nếu bạn thực sự thêm nội dung (cần có trong thẻ body). Ngoài ra thẻ script của bạn thiếu một loại. Không bao giờ dựa vào các trình duyệt sửa mã không tuân thủ tiêu chuẩn của bạn! (Vì các trình duyệt có thể làm khác đi hoặc không hoàn toàn trong quá khứ hoặc tương lai.)
Kissaki

4
@Kissaki: HTML tiêu chuẩn hoàn toàn không cần thẻ body!
Robert Siemer

5
xhtml1 quy định cụ thể <!ELEMENT html (head, body)>[1] - và html401 quy định cụ thể <!ELEMENT HTML O O (%html.content;)với <!ENTITY % html.content "HEAD, BODY">cũng [2]. trạng thái html51 A head element followed by a body element.cho nội dung html là tốt. [3] w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict w3.org/TR/html51/semantics.html -html-Element - Vì vậy, tôi đoán tất cả các tiêu chuẩn HTML phổ biến / đang sử dụng này đều yêu cầu thẻ body. :)
Kissaki

1
@Kissaki đó là XHTML, không phải HTML. HTML cho phép bỏ qua thẻ của cả thẻ bắt đầu và kết thúc, cũng như bỏ qua thẻ html và thẻ đầu, theo DTD SGML của nó. w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoding

1
@Kissaki: html5 không cần loại tập lệnh nữa (nếu là javascript), bạn phù hợp với các phiên bản trước.
Đánh dấu

10

Tôi thích, nói chung, không sử dụng <body onload=""sự kiện>. Tôi nghĩ sẽ tốt hơn nếu giữ hành vi tách biệt với nội dung càng nhiều càng tốt.

Điều đó nói rằng, có những dịp (thường khá hiếm đối với tôi) khi sử dụng body onload có thể giúp tăng tốc độ nhẹ.

Tôi thích sử dụng Prototype vì vậy tôi thường đặt một cái gì đó như thế này vào <head> trang của mình:

document.observe("dom:loaded", function(){
  alert('The DOM is loaded!');
});

hoặc là

Event.observe(window, 'load', function(){
  alert('Window onload');
});

Trên đây là những thủ thuật tôi học được ở đây . Tôi rất thích khái niệm đính kèm các trình xử lý sự kiện bên ngoài HTML.

(Chỉnh sửa để sửa lỗi chính tả trong mã.)


Trong những dịp nào nó sẽ nhanh hơn, và tại sao?
Kissaki

Câu trả lời này có vẻ rất chủ quan với tất cả các phiên bản của tôi. Rằng nếu thiếu thêm bất kỳ sự thật khách quan và có thể kiểm chứng được thì sẽ hỗ trợ rất nhiều cho ấn tượng đó.
Kissaki

1
Tôi sẽ lấy câu trả lời này bằng một hạt muối xem xét nó đã được đăng hơn 6 năm trước. Bạn được chào đón để cập nhật nó hoặc đăng câu trả lời được cải thiện của riêng bạn.
Mark Biek

7

'Rất nhiều câu trả lời chủ quan cho một câu hỏi khách quan. JavaScript "không phô trương" là mê tín như quy tắc cũ không bao giờ sử dụng gotos. Viết mã theo cách giúp bạn hoàn thành mục tiêu của mình một cách đáng tin cậy, không theo niềm tin tôn giáo hợp thời của ai đó.

Bất cứ ai tìm thấy:

 <body onload="body_onload();">

bị phân tâm quá mức là quá tự phụ và không có ưu tiên của họ.

Tôi thường đặt mã JavaScript của mình vào một tệp .js riêng biệt, nhưng tôi thấy không có gì rườm rà về việc xử lý các trình xử lý sự kiện trong HTML, đây là HTML hợp lệ.


39
Có lý do chính đáng để viết javascript không phô trương. Giả sử bạn có một ứng dụng web có 100 trang và bạn đã sử dụng phương thức <body onload = "body_onload ();"> thay vì đưa nó vào tệp javascript được bao gồm bởi mỗi trang. Sau đó tưởng tượng bạn cần thay đổi tên của chức năng đó vì một số lý do. Việc đưa sự kiện vào tệp javascript đi kèm 1) giúp thay đổi đơn giản hơn rất nhiều và 2) tiết kiệm tài nguyên máy chủ vì các tệp javascript có thể được lưu trong bộ nhớ cache trong một năm (trên máy chủ được định cấu hình đúng) thay vì lặp đi lặp lại cùng một mã.
Andrew Oblley

21
Vì vậy, vì bạn không bận tâm tìm hiểu lý do tại sao một cái gì đó được khuyến nghị nên bạn dán nhãn cho các khuyến nghị "niềm tin tôn giáo hợp thời" ??
hallvors

6
Câu hỏi đặt ra là "sự khác biệt giữa hai phương pháp này là gì?", Cùng với yêu cầu đề xuất phương pháp nào tốt hơn. Làm thế nào để trả lời của bạn trả lời câu hỏi đó?
Richard Turner

1
Bất kỳ tình huống nào bạn thực hiện một giải pháp mô-đun ở 1 vị trí có thể được áp dụng cho một khối lượng lớn tệp sẽ tốt hơn nhiều so với việc thêm mã vào từng khối lượng tệp. Nó tốt hơn cho thời gian xây dựng ban đầu, mục đích tổ chức mã, cho khả năng đọc và chỉnh sửa trong tương lai. Nó không hợp thời trang, nó thực sự là một khái niệm cũ hơn hiện diện trong các ngôn ngữ như java và c ++ mà các lập trình viên web hiện đang chấp nhận như là cách tốt hơn để viết mã.
Jimbo Jonny

1
Một biện pháp bảo vệ tốt chống lại các cuộc tấn công XSS trong các trình duyệt hiện đại là vô hiệu hóa tất cả các javascript nội tuyến với Chính sách bảo mật nội dung của bạn. Đó là một lý do khá chính đáng để không sử dụng thuộc tính onload trong HTML của bạn.
Greg Ball

4

window.onload- Được gọi sau khi tất cả các tệp DOM, JS, Hình ảnh, Iframes, Tiện ích mở rộng và các tệp khác được tải hoàn toàn. Điều này bằng $ (cửa sổ) .load (function () {});

body onload=""- Được gọi một khi DOM được tải. Giá trị này bằng $ (tài liệu). Đã (hàm () {});


1
Là ai đó có thể nguồn này? Tôi đã thấy tuyên bố này trên nhiều diễn đàn nhưng không bao giờ có liên kết đến nơi được xác định trong thông số kỹ thuật.
crempp

1
@crempp Có yếu tố cơ thểthuộc tính Toàn cầu , vì vậy tôi sẽ nói điều này không đúng. Nhưng bạn có thể tự kiểm tra điều này, xem jsbin.com/OmiViPAJ/1/edit . Ở đó, bạn có thể thấy sự kiện tải hình ảnh được kích hoạt trước sự kiện tải trọng cơ thể.
Olaf Dietsche

2
Câu trả lời này mâu thuẫn với người khác; bạn có thể cung cấp một nguồn?
Jimmy Breck-McKye

2
api.jquery.com/ yet Các tài liệu jQuery nói: "Phương thức. yet () thường không tương thích với thuộc tính <body onload =" ">." Tôi nghĩ trong jQuery gần với body.onload $ (window) .load (..) nhưng tôi nghĩ chúng vẫn khác nhau.
ccsakuweb

2
Câu trả lời này là hoàn toàn sai và không nên có bất kỳ phiếu bầu nào. Trong thực tế, loại câu trả lời này thường được trích dẫn là một trong những quan niệm sai lầm lớn nhất về readyvs onloadcác sự kiện. loadkích hoạt sau khi toàn bộ tài liệu được tải bao gồm tất cả các tập lệnh, hình ảnh và biểu định kiểu. DOMContentLoadedcháy sau khi cây DOM đã được xây dựng nhưng trước hình ảnh, v.v. Nó DOMContentLoadedcó tương đương với document.ready, không load.
nghĩa

2

Không sự khác biệt ...

Vì vậy, về cơ bản, bạn có thể sử dụng cả hai (một lần! -)

Nhưng vì mục đích dễ đọc và vì sự sạch sẽ của mã html, tôi luôn thích window.onload! O]


1

Nếu bạn đang cố gắng viết mã JS không phô trương (và bạn nên như vậy), thì bạn không nên sử dụng <body onload="">.

Theo hiểu biết của tôi, các trình duyệt khác nhau xử lý hai trình duyệt này hơi khác nhau nhưng chúng hoạt động tương tự nhau. Trong hầu hết các trình duyệt, nếu bạn xác định cả hai, một cái sẽ bị bỏ qua.


1

Hãy nghĩ về onload như bất kỳ thuộc tính khác. Trên một hộp đầu vào, ví dụ, bạn có thể đặt:

<input id="test1" value="something"/>

Hoặc bạn có thể gọi:

document.getElementById('test1').value = "somethingelse";

Thuộc tính onload hoạt động theo cùng một cách, ngoại trừ việc nó lấy một hàm làm giá trị của nó thay vì một chuỗi như thuộc tính value. Điều đó cũng giải thích lý do tại sao bạn "chỉ có thể sử dụng một trong số chúng" - gọi window.onload gán lại giá trị của thuộc tính onload cho thẻ body.

Ngoài ra, giống như những người khác ở đây đang nói, thông thường sẽ giữ phong cách và javascript tách biệt với nội dung của trang, đó là lý do tại sao hầu hết mọi người khuyên nên sử dụng window.onload hoặc như chức năng sẵn sàng của jQuery.


1

<body onload = ""> nên ghi đè window.onload.

Với <body onload = "">, document.body.onload có thể là null, không xác định hoặc một hàm tùy thuộc vào trình duyệt (mặc dù getAttribution ("onload") có thể nhất quán để lấy phần thân của hàm ẩn danh dưới dạng chuỗi) . Với window.onload, khi bạn gán một hàm cho nó, window.onload sẽ là một hàm nhất quán trên các trình duyệt. Nếu điều đó quan trọng với bạn, hãy sử dụng window.onload.

window.onload tốt hơn cho việc tách JS khỏi nội dung của bạn. Không có nhiều lý do để sử dụng <body onload = ""> dù sao khi bạn có thể sử dụng window.onload.

Trong Opera, mục tiêu sự kiện cho window.onload và <body onload = ""> (và thậm chí window.addEventListener ("load", func, false)) sẽ là cửa sổ thay vì tài liệu như trong Safari và Firefox. Nhưng, 'cái này' sẽ là cửa sổ trên các trình duyệt.

Điều này có nghĩa là, khi nó quan trọng, bạn nên bọc lại và làm cho mọi thứ nhất quán hoặc sử dụng một thư viện làm điều đó cho bạn.


0

Cả hai đều làm việc như nhau. Tuy nhiên, lưu ý rằng nếu cả hai được xác định, chỉ một trong số chúng sẽ được gọi. Tôi thường tránh sử dụng một trong hai trực tiếp. Thay vào đó, bạn có thể đính kèm một trình xử lý sự kiện vào sự kiện tải. Bằng cách này, bạn có thể kết hợp dễ dàng hơn các gói JS khác mà cũng có thể cần phải gọi lại cho sự kiện onload.

Bất kỳ khung JS nào cũng sẽ có các phương thức trình duyệt chéo cho các trình xử lý sự kiện.


0

Đó là một tiêu chuẩn được chấp nhận để có nội dung, bố cục và hành vi riêng biệt. Vì vậy, window.onload () sẽ phù hợp để sử dụng hơn <body onload="">mặc dù cả hai đều làm cùng một công việc.


0

Xin lỗi vì tái sinh chủ đề này một lần nữa sau 3 năm ngủ, nhưng có lẽ cuối cùng tôi đã tìm thấy lợi ích không thể chối cãi của window.onload=fn1;hơn <body onload="fn1()">. Nó liên quan đến các mô-đun JS hoặc mô-đun ES : khi onloadtrình xử lý của bạn nằm trong tệp JS "cổ điển" (nghĩa là không <script type="module" … >có cách nào khả thi; khi onloadtrình xử lý của bạn nằm trong tệp JS "mô-đun" (được gọi là <script type="module" … >, <body onload="fn1()">sẽ thất bại với "fn1 () không được xác định "lỗi. Lý do có lẽ là các mô-đun ES không được tải trước khi HTML được phân tích cú pháp nhưng đó chỉ là phỏng đoán của tôi. Dù sao đi nữa, window.onload=fn1;hoạt động hoàn hảo với các mô-đun ...

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.