Làm cách nào để JavaScript thực thi sau khi tải trang?


737

Tôi đang thực hiện một tập lệnh bên ngoài, sử dụng một <script>bên trong <head>.

Bây giờ vì tập lệnh thực thi trước khi trang được tải, tôi không thể truy cập <body>, trong số những thứ khác. Tôi muốn thực thi một số JavaScript sau khi tài liệu đã được "tải" (HTML được tải xuống đầy đủ và trong RAM). Có bất kỳ sự kiện nào tôi có thể nối vào khi tập lệnh của tôi thực thi, điều đó sẽ được kích hoạt khi tải trang không?

Câu trả lời:


837

Những giải pháp này sẽ hoạt động:

<body onload="script();">

hoặc là

document.onload = function ...

hoặc thậm chí

window.onload = function ...

Lưu ý rằng tùy chọn cuối cùng là một cách tốt hơn để đi vì nó không quan trọng và được coi là tiêu chuẩn hơn .


5
Sự khác biệt giữa <body onload = "script ();"> và document.onload = function ... là gì?
Mentoliptus

11
@mentoliptus: document.onload=là không gây khó chịu en.wikipedia.org/wiki/Unobtrusive_JavaScript
marcgg

3
tập lệnh trong html ... không không không $ (function () {code here}); <- javascript.js có thể được đặt trong đầu và sẽ tải sau DOM

21
@gerdi OP không đề cập gì về jQuery. Tôi cũng đưa ra một lựa chọn không phô trương trong câu trả lời của mình.
marcgg

1
document.onload không làm việc cho tôi. Tôi tìm thấy bài đăng này với cùng một vấn đề stackoverflow.com/questions/5135638/ . Không có vẻ như document.onload là một tùy chọn.
spốmmahn

196

Cách di chuyển hợp lý, không theo khung để tập lệnh của bạn thiết lập một chức năng để chạy khi tải:

if(window.attachEvent) {
    window.attachEvent('onload', yourFunctionName);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            yourFunctionName(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = yourFunctionName;
    }
}

10
+1 để đăng gần như chính xác những gì tôi đã đưa ra 6 tháng trước. Mã như thế này có thể cần thiết nếu các khung và mã khác mà bạn không kiểm soát được đang thêm các sự kiện onload và bạn cũng muốn mà không xóa sạch các sự kiện onload khác. Tôi đã bao gồm việc thực hiện của mình như là một hàm và nó yêu cầu var newonload = function (evt) {curronload (evt); tải trọng mới (evt); } bởi vì một số lý do, khung công tác tôi đang sử dụng yêu cầu một sự kiện được chuyển đến sự kiện onload.
Grant Wagner

6
Tôi vừa phát hiện ra rằng kiểm tra mã dưới dạng kết quả bằng văn bản trong trình xử lý bị sa thải theo thứ tự không xác định khi được đính kèm với Đính kèm (). Nếu việc thực hiện lệnh xử lý là quan trọng, bạn có thể muốn rời khỏi nhánh window.attachEvent.
Cấp Wagner

Vì vậy, điều này sẽ thêm chức năng này như là một chức năng THÊM để chạy OnLoad, đúng không? (thay vì thay thế một sự kiện onload hiện có)
Clay Nichols

@ClayNichols: Đúng.
hỗn loạn

2
Giải pháp tốt, nhưng hiện đã lỗi thời: developer.mozilla.org/en-US/docs/Web/API/EventTarget/
Kẻ

192

Hãy nhớ rằng tải trang có nhiều hơn một giai đoạn. Btw, đây là JavaScript thuần

"DOMContentLoaded"

Sự kiện này đượ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. Ở giai đoạn này, bạn có thể lập trình tối ưu hóa việc tải hình ảnh và css dựa trên thiết bị người dùng hoặc tốc độ băng thông.

Thực thi sau khi DOM được tải (trước img và css):

document.addEventListener("DOMContentLoaded", function(){
    //....
});

Lưu ý: JavaScript đồng bộ tạm dừng phân tích cú pháp DOM. Nếu bạn muốn DOM được phân tích cú pháp nhanh nhất có thể sau khi người dùng yêu cầu trang, bạn có thể biến JavaScript không đồng bộtối ưu hóa tải biểu định kiểu

"tải"

Một sự kiện rất khác nhau, tải , chỉ nên được sử dụng để phát hiện một trang được tải đầy đủ . Đó là một lỗi cực kỳ phổ biến khi sử dụng tải trong đó DOMContentLoaded sẽ phù hợp hơn nhiều, vì vậy hãy thận trọng.

Các ngoại lệ sau khi mọi thứ được tải và phân tích cú pháp:

window.addEventListener("load", function(){
    // ....
});

Tài nguyên MDN:

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load

Danh sách MDN của tất cả các sự kiện:

https://developer.mozilla.org/en-US/docs/Web/Events


1
@Peter khá chắc chắn rằng điều này đứng một mình có lẽ là tốt nhất nếu nó ở dưới cùng của tệp javascript của bạn để nó thực thi lần cuối
arodebaugh

Javascript tạm dừng kết xuất DOM ở đó theo cách tốt nhất là đặt nó ở cuối trang hoặc tải javascript async trong tiêu đề.
DevWL

Đây là câu trả lời đầy đủ nhất. onload là sau, nhưng mọi người không nhận ra điều này lúc đầu.
tfont

1
Re- javascript không đồng bộ : để làm rõ, có hai lựa chọn cho các tập lệnh không chạy ngay lập tức. Trong số đó, defer thường được ưu tiên hơn so với async - bởi vì defer sẽ không làm gián đoạn phân tích / kết xuất html - và khi nó chạy, DOM được đảm bảo sẵn sàng. Tải JavaScript hiệu quả với defer và async .
ToolmakerSteve

+1 Tôi đã cố gắng window.onload = ...nghĩ rằng kịch bản của mình sẽ đợi cho đến khi mọi thứ được tải xuống đầy đủ trước khi chạy nhưng có vẻ như nó window.onloadthực sự hoạt động như thế document.addEventListener("DOMContentLoaded", ..., trong khi window.addEventListener("load", ...thực sự chờ mọi thứ được tải xuống đầy đủ. Tôi có thể nghĩ rằng window.onloadnên tương đương với window.addEventListener("load", ...chứ không phải document.addEventListener("DOMContentLoaded", ...?? Tôi đã nhận được kết quả tương tự trong Chrome và FF.
wkille

121

Bạn có thể đặt thuộc tính "onload" bên trong cơ thể

...<body onload="myFunction()">...

Hoặc nếu bạn đang sử dụng jQuery, bạn có thể làm

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

or 

$(window).load(function(){ /*code here*/ })

Tôi hy vọng nó trả lời câu hỏi của bạn.

Lưu ý rằng $ (window) .load sẽ thực thi sau khi tài liệu được hiển thị trên trang của bạn.


65

Nếu các tập lệnh được tải trong <head>tài liệu, thì có thể sử dụng deferthuộc tính trong thẻ tập lệnh.

Thí dụ:

<script src="demo_defer.js" defer></script>

Từ https://developer.mozilla.org :

hoãn lại

Thuộc tính Boolean này được đặt để chỉ ra cho trình duyệt rằng tập lệnh có nghĩa là được thực thi sau khi tài liệu được phân tích cú pháp, nhưng trước khi bắn DOMContentLoaded.

Thuộc tính này không được sử dụng nếu thuộc tính src vắng mặt (tức là đối với các tập lệnh nội tuyến), trong trường hợp này nó sẽ không có hiệu lực.

Để đạt được hiệu ứng tương tự cho các tập lệnh được chèn động, thay vào đó, hãy sử dụng async = false. Các tập lệnh với thuộc tính defer sẽ thực thi theo thứ tự xuất hiện trong tài liệu.


Tôi thích giải pháp này, vì không cần bất kỳ mã javascript nào, nhưng chỉ cần một thuộc tính html <3
sarkiroka

27

Đây là tập lệnh dựa trên tải js hoãn lại sau khi trang được tải,

<script type="text/javascript">
  function downloadJSAtOnload() {
      var element = document.createElement("script");
      element.src = "deferredfunctions.js";
      document.body.appendChild(element);
  }

  if (window.addEventListener)
      window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

Tôi đặt cái này ở đâu?

Dán mã vào HTML của bạn ngay trước </body>thẻ (gần cuối tệp HTML của bạn).

Nó làm gì?

Mã này cho biết chờ toàn bộ tài liệu tải, sau đó tải tệp bên ngoài deferredfunctions.js.

Đây là một ví dụ về đoạn mã trên - Trì hoãn kết xuất của JS

Tôi đã viết điều này dựa trên việc tải xuống các trang javascript của khái niệm google và cũng có nguồn gốc từ bài viết này Trì hoãn tải javascript


20

Nhìn vào hooking document.onloadhoặc trong jQuery $(document).load(...).


Sự kiện này có đáng tin cậy không? (Trình duyệt chéo .. IE6 + FF2 +, v.v.)
TheFlash

1
Có, đây là trình duyệt chéo, DOM tiêu chuẩn.
Daniel A. White

16
Đó thực sự là window.onload đó là tiêu chuẩn hơn, không phải là document.onload. AFAIK
Peter Bailey

11

Làm việc trên<body onload="myFunction()">

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
   function myFunction(){
    alert("Page is loaded");
   }
  </script>
 </head>

 <body onload="myFunction()">
  <h1>Hello World!</h1>
 </body>    
</html>

10
<script type="text/javascript">
  function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "defer.js";
   document.body.appendChild(element);
  }
  if (window.addEventListener)
   window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
   window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

http://www.feedthebot.com/pagespeed/defer-loading-javascript.html




7

Đôi khi tôi thấy trên các trang phức tạp hơn mà không phải tất cả các yếu tố đã được tải bởi cửa sổ thời gian.onload được kích hoạt. Nếu đó là trường hợp, thêm setTimeout trước khi chức năng của bạn bị trì hoãn là một khoảnh khắc. Nó không thanh lịch nhưng đó là một hack đơn giản mà kết xuất tốt.

window.onload = function(){ doSomethingCool(); };

trở thành ...

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };

5

Chỉ cần xác định <body onload="aFunction()">rằng sẽ được gọi sau khi trang đã được tải. Mã của bạn trong tập lệnh được bao bọc bởi aFunction() { }.


4
<body onload="myFunction()">

Mã này hoạt động tốt.

Nhưng window.onloadphương pháp có sự phụ thuộc khác nhau. Vì vậy, nó có thể không hoạt động tất cả các thời gian.


3

Sử dụng thư viện YUI (tôi thích nó):

YAHOO.util.Event.onDOMReady(function(){
    //your code
});

Di động và đẹp! Tuy nhiên, nếu bạn không sử dụng YUI cho những thứ khác (xem tài liệu của nó) tôi sẽ nói rằng nó không đáng để sử dụng nó.

NB: để sử dụng mã này, bạn cần nhập 2 tập lệnh

<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>

3

Có một tài liệu rất hay về Cách phát hiện nếu tài liệu đã được tải bằng Javascript hoặc Jquery.

Sử dụng Javascript gốc có thể đạt được điều này

if (document.readyState === "complete") {
 init();
 }

Điều này cũng có thể được thực hiện trong khoảng

var interval = setInterval(function() {
    if(document.readyState === 'complete') {
        clearInterval(interval);
        init();
    }    
}, 100);

Ví dụ: bởi Mozilla

switch (document.readyState) {
  case "loading":
    // The document is still loading.
    break;
  case "interactive":
    // The document has finished loading. We can now access the DOM elements.
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // The page is fully loaded.
    console.log("Page is loaded completely");
    break;
}

Sử dụng Jquery Để chỉ kiểm tra nếu DOM đã sẵn sàng

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

Để kiểm tra xem tất cả tài nguyên đã được tải chưa, hãy sử dụng window.load

 $( window ).load(function() {
        console.log( "window loaded" );
    });

3

Sử dụng mã này với thư viện jQuery, điều này sẽ hoạt động hoàn toàn tốt.

$(window).bind("load", function() { 

  // your javascript event

});

Thêm một số mô tả ở đây
Mathews Sunny

3
$(window).on("load", function(){ ... });

. yet () hoạt động tốt nhất cho tôi.

$(document).ready(function(){ ... });

.load () sẽ hoạt động, nhưng sẽ không đợi đến khi trang được tải.

jQuery(window).load(function () { ... });

Không làm việc cho tôi, phá vỡ tập lệnh nội tuyến kế tiếp. Tôi cũng đang sử dụng jQuery 3.2.1 cùng với một số nhánh jQuery khác.

Để ẩn trang web của tôi đang tải lớp phủ, tôi sử dụng như sau:

<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>

3

JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

tương tự với jQuery:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});





LƯU Ý: - Không sử dụng đánh dấu bên dưới (vì nó ghi đè các khai báo cùng loại khác):

document.onreadystatechange = ...

1

Như Daniel nói, bạn có thể sử dụng document.onload.

Các khung javascript khác nhau bất kỳ lúc nào (jQuery, Mootools, v.v.) sử dụng một sự kiện tùy chỉnh 'dom yet', mà tôi đoán phải hiệu quả hơn. Nếu bạn đang phát triển bằng javascript, tôi khuyên bạn nên khai thác một khung, chúng sẽ tăng năng suất của bạn một cách ồ ạt.



0

Lời khuyên của tôi là sử dụng asnycthuộc tính cho thẻ script giúp bạn tải các tập lệnh bên ngoài sau khi tải trang

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>

7
Theo w3schools , Nếu có async: Tập lệnh được thực thi không đồng bộ với phần còn lại của trang (tập lệnh sẽ được thực thi trong khi trang tiếp tục phân tích cú pháp) . Có lẽ bạn có ý deferthay vào đó, như @Daniel Price đã đề cập?
jk7

0

sử dụng chức năng tự thực hiện tải

window.onload = function (){
    /* statements */
}();   

2
Bạn có thể ghi đè các onloadtrình xử lý khác bằng cách sử dụng phương pháp này. Thay vào đó, bạn nên thêm người nghe.
Leonid Dashko
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.