จะทำให้ JavaScript ทำงานหลังจากโหลดหน้าเว็บได้อย่างไร


737

ฉันรันสคริปต์ภายนอกใช้ภายใน<script><head>

ตอนนี้เนื่องจากสคริปต์ทำงานก่อนหน้าโหลดฉันไม่สามารถเข้าถึง<body>เหนือสิ่งอื่นใด ฉันต้องการเรียกใช้งาน JavaScript บางส่วนหลังจากเอกสาร "โหลดแล้ว" (ดาวน์โหลด HTML ทั้งหมดและในแรม) มีเหตุการณ์ใดบ้างที่ฉันสามารถขอเมื่อสคริปต์ของฉันดำเนินการที่จะถูกเรียกใช้ในการโหลดหน้า?

คำตอบ:


836

โซลูชั่นเหล่านี้จะทำงาน:

<body onload="script();">

หรือ

document.onload = function ...

หรือแม้กระทั่ง

window.onload = function ...

สังเกตได้ว่า ตัวเลือกสุดท้ายคือวิธีที่ดีกว่าที่จะไปเพราะมันเป็นunobstrusiveและถือเป็นมาตรฐานมากขึ้น


5
อะไรคือความแตกต่างระหว่าง <body onload = "script ();"> และ document.onload = function ... ?
Mentoliptus

11
@mentoliptus: document.onload=ไม่เสือก en.wikipedia.org/wiki/Unobtrusive_JavaScript
marcgg

3
สคริปต์ใน html ... ไม่ไม่ $ (function () {code here}); <- javascript.js สามารถวางไว้ในหัวและจะโหลดหลังจาก DOM

21
@gerdi OP ไม่ได้พูดถึงอะไรเกี่ยวกับ jQuery ฉันยังให้ตัวเลือกที่ไม่เป็นการรบกวนในคำตอบของฉัน
marcgg

1
document.onload ไม่ทำงานสำหรับฉัน ฉันพบโพสต์นี้ด้วยปัญหาstackoverflow.com/questions/5135638//เดียวกัน ดูเหมือนจะไม่เป็น document.onload เป็นตัวเลือก
spottedmahn

196

แบบพกพาที่สมเหตุสมผลและไม่ใช่เฟรมเวิร์กเพื่อให้สคริปต์ของคุณตั้งค่าฟังก์ชันให้ทำงานที่เวลาโหลด:

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 สำหรับโพสต์สิ่งที่ฉันต้องทำเมื่อ 6 เดือนที่แล้ว โค้ดเช่นนี้อาจจำเป็นถ้าเฟรมเวิร์กและโค้ดอื่นที่คุณไม่สามารถควบคุมได้คือการเพิ่มเหตุการณ์ onload และคุณต้องการเช่นกันโดยไม่ต้องลบเหตุการณ์ onload อื่น ๆ ฉันรวมการใช้งานของฉันเป็นฟังก์ชันและจำเป็นต้องมี var newonload = function (evt) {curronload (evt); newOnload (EVT); } เพราะเหตุผลบางประการที่เฟรมเวิร์กที่ฉันใช้ต้องการให้เหตุการณ์ถูกส่งผ่านไปยังเหตุการณ์ onload
Grant Wagner

6
ฉันเพิ่งค้นพบในการทดสอบว่าโค้ดที่เป็นผลการเขียนในตัวจัดการถูกไล่ออกตามลำดับที่ไม่ได้กำหนดเมื่อแนบกับ attachEvent () หากคำสั่งของการจัดการดำเนินการเป็นสิ่งสำคัญคุณอาจต้องการออกจากหน้าต่างสาขาติดต่อเหตุการณ์
Grant Wagner

ดังนั้นสิ่งนี้จะเพิ่มฟังก์ชั่นนี้เป็นฟังก์ชั่นเพิ่มเติมเพื่อเรียกใช้ OnLoad ถูกต้อง? (แทนที่จะแทนที่เหตุการณ์ onload ที่มีอยู่)
Clay Nichols

@ClayNichols: ถูกต้อง
ความโกลาหล

2
วิธีแก้ปัญหาที่ดี แต่ล้าสมัยแล้ว: developer.mozilla.org/en-US/docs/Web/API/EventTarget/…
Renan

192

โปรดทราบว่าการโหลดหน้าเว็บมีมากกว่าหนึ่งเวที Btw นี่คือจาวาสคริปต์ที่บริสุทธิ์

"DOMContentLoaded"

เหตุการณ์นี้เกิดขึ้นเมื่อเอกสาร HTML เริ่มต้นถูกโหลดและวิเคราะห์โดยสมบูรณ์โดยไม่ต้องรอสไตล์ชีตรูปภาพและเฟรมย่อยเพื่อให้การโหลดเสร็จสิ้น ในขั้นตอนนี้คุณสามารถปรับการโหลดรูปภาพและ css โดยทางโปรแกรมโดยขึ้นอยู่กับอุปกรณ์ผู้ใช้หรือความเร็วแบนด์วิดท์

ดำเนินการหลังจากโหลด DOM (ก่อนหน้า img และ css):

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

หมายเหตุ: JavaScript แบบซิงโครนัสจะหยุดการแยกวิเคราะห์ DOM ชั่วคราว หากคุณต้องการให้ DOM แยกวิเคราะห์โดยเร็วที่สุดหลังจากผู้ใช้ร้องขอหน้าคุณสามารถเปิด JavaScript แบบอะซิงโครนัสและเพิ่มประสิทธิภาพการโหลดสไตล์ชีท

"ภาระ"

เหตุการณ์ที่แตกต่างกันมากโหลดควรจะใช้เฉพาะในการตรวจสอบหน้าอย่างเต็มที่โหลด มันเป็นความผิดพลาดที่ได้รับความนิยมอย่างไม่น่าเชื่อในการใช้โหลดโดยที่ DOMContentLoaded จะมีความเหมาะสมมากกว่าดังนั้นควรระมัดระวัง

มีข้อผิดพลาดหลังจากทุกอย่างถูกโหลดและแยกวิเคราะห์:

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

ทรัพยากร MDN:

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

รายการ MDN ของเหตุการณ์ทั้งหมด:

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


1
@ Peter สวยแน่ใจว่านี้ยืนอยู่คนเดียวน่าจะดีที่สุดถ้ามันในด้านล่างของไฟล์จาวาสคริปต์ของคุณเพื่อให้มันรันสุดท้าย
arodebaugh

Javascript หยุดการเรนเดอร์ของ DOM ที่นั่นเพื่อวิธีที่ดีที่สุดคือการวางไว้ที่ด้านล่างของหน้าหรือโหลด javascript async ในส่วนหัว
DevWL

นี่คือคำตอบที่สมบูรณ์ที่สุด onload นั้นเกิดขึ้น แต่ผู้คนไม่ได้ตระหนักถึงสิ่งนี้ในตอนแรก
tfont

1
จาวาสคริปต์แบบอะซิงโครนัสอีกครั้ง : เพื่อชี้แจงมีสองตัวเลือกสำหรับสคริปต์ที่ไม่ได้ทำงานทันที โดยทั่วไปแล้วการเลื่อนเวลาจะเป็นที่นิยมกว่าในการasyncเนื่องจากการเลื่อนจะไม่ขัดขวางการแยก / การเรนเดอร์ html และเมื่อมันรัน DOM รับประกันว่าพร้อมที่จะพร้อมใช้งาน ได้อย่างมีประสิทธิภาพโหลด javascript กับ Defer และ async
ToolmakerSteve

+1 ฉันลองwindow.onload = ...คิดว่าสคริปต์ของฉันจะรอจนกว่าทุกอย่างจะถูกดาวน์โหลดอย่างสมบูรณ์ก่อนที่จะทำงาน แต่ดูเหมือนว่ามันจะwindow.onloadมีพฤติกรรมเหมือนจริงdocument.addEventListener("DOMContentLoaded", ...ในขณะที่window.addEventListener("load", ...ทุกอย่างจะรอให้ดาวน์โหลดทุกอย่างจริงๆ ผมจะมีความคิดว่าwindow.onloadควรจะเทียบเท่ากับwindow.addEventListener("load", ...มากกว่าdocument.addEventListener("DOMContentLoaded", ...?? ฉันได้รับผลลัพธ์เดียวกันใน Chrome และ FF
wkille

121

คุณสามารถใส่แอตทริบิวต์ "onload" ไว้ในเนื้อความ

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

หรือถ้าคุณใช้ jQuery คุณสามารถทำได้

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

or 

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

ฉันหวังว่ามันจะตอบคำถามของคุณ

โปรดทราบว่า $ (หน้าต่าง). load จะดำเนินการหลังจากสร้างเอกสารบนหน้าของคุณ


65

หากสคริปต์โหลดภายใน<head>เอกสารอาจเป็นไปได้ที่จะใช้deferแอตทริบิวต์ในแท็กสคริปต์

ตัวอย่าง:

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

จาก https://developer.mozilla.org :

Defer

แอ็ตทริบิวต์ Boolean นี้ถูกตั้งค่าให้บ่งบอกถึงเบราว์เซอร์ที่สคริปต์นั้นมีความหมายว่าจะต้องดำเนินการหลังจากที่เอกสารถูกแยกวิเคราะห์ แต่ก่อนที่จะทำการยิง DOMContentLoaded

ต้องไม่ใช้แอตทริบิวต์นี้หากแอตทริบิวต์ src ขาด (เช่นสำหรับสคริปต์แบบอินไลน์) ในกรณีนี้มันจะไม่มีผล

เพื่อให้ได้ผลคล้ายกันสำหรับสคริปต์ที่แทรกแบบไดนามิกให้ใช้ async = false แทน สคริปต์ที่มีแอตทริบิวต์ defer จะทำงานตามลำดับที่ปรากฏในเอกสาร


ฉันรักโซลูชันนี้เพราะไม่ต้องการรหัส javascript ใด ๆ แต่ต้องการเพียงหนึ่งคุณลักษณะ html <3
sarkiroka

27

นี่คือสคริปต์ตาม js รอการโหลดหลังจากโหลดหน้าเว็บแล้ว

<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>

ฉันจะวางที่ไหน

วางรหัสใน HTML ของคุณหน้า</body>แท็ก (ใกล้กับด้านล่างของไฟล์ HTML)

มันทำอะไร?

deferredfunctions.jsรหัสนี้กล่าวว่ารอให้เอกสารทั้งหมดที่จะโหลดแล้วโหลดไฟล์ภายนอก

นี่คือตัวอย่างของรหัสข้างต้น - เลื่อนการแสดงผลของ JS

ฉันเขียนสิ่งนี้ขึ้นอยู่กับการโหลดที่เลื่อนออกไปของ javascript pagespeed google concept และแหล่งที่มาจากบทความนี้Defer loading javascript


20

ดู hooking document.onloadหรือ $(document).load(...)jQuery


เหตุการณ์นี้เชื่อถือได้หรือไม่? (ข้ามเบราว์เซอร์ .. IE6 + FF2 + ฯลฯ )
TheFlash

1
ใช่นี่คือข้ามเบราว์เซอร์ DOM มาตรฐาน
Daniel A. White

16
จริง ๆ แล้วมันเป็นหน้าต่างการโหลดที่เป็นมาตรฐานมากกว่าไม่ใช่การโหลดเอกสาร AFAIK
Peter Bailey


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

บางครั้งฉันพบว่าในหน้าเว็บที่ซับซ้อนมากขึ้นซึ่งองค์ประกอบบางอย่างไม่ได้โหลดตามเวลาที่กำหนด หากเป็นกรณีนี้ให้เพิ่ม setTimeout ก่อนที่ฟังก์ชันของคุณจะหน่วงเวลาสักครู่ มันไม่ได้สวยงาม แต่มันเป็นแฮ็คที่เรียบง่ายที่แสดงผลได้ดี

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

กลายเป็น...

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

5

เพียงแค่กำหนด<body onload="aFunction()">ว่าจะถูกเรียกหลังจากโหลดหน้าเว็บแล้ว aFunction() { }รหัสของคุณในสคริปต์กว่าล้อมรอบด้วย


4
<body onload="myFunction()">

รหัสนี้ทำงานได้ดี

แต่window.onloadวิธีการมีการพึ่งพาต่าง ๆ ดังนั้นมันอาจไม่ทำงานตลอดเวลา


3

ใช้ห้องสมุด YUI (ฉันชอบมาก):

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

พกพาสะดวกและสวยงาม! อย่างไรก็ตามหากคุณไม่ได้ใช้ YUI สำหรับสิ่งอื่น ๆ (ดูเอกสารของมัน) ฉันจะบอกว่ามันไม่คุ้มค่าที่จะใช้

หมายเหตุ: ในการใช้รหัสนี้คุณต้องนำเข้า 2 สคริปต์

<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

มีเอกสารที่ดีมากเกี่ยวกับวิธีการตรวจสอบว่าเอกสารโหลดโดยใช้ Javascript หรือ Jquery

การใช้ Javascript ดั้งเดิมสามารถทำได้

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

สิ่งนี้สามารถทำได้ภายในช่วงเวลา

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

เช่นโดย 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;
}

ใช้ Jquery เพื่อตรวจสอบเฉพาะในกรณีที่ DOM พร้อม

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

เพื่อตรวจสอบว่าโหลดทรัพยากรทั้งหมดใช้ window.load หรือไม่

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

3

ใช้รหัสนี้กับห้องสมุด jQuery สิ่งนี้จะทำงานได้อย่างสมบูรณ์แบบ

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

  // your javascript event

});

เพิ่มคำอธิบายที่นี่
Mathews Sunny

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

.ready ()ทำงานได้ดีที่สุดสำหรับฉัน

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

.load ()จะทำงานได้ แต่จะไม่รอจนกว่าจะโหลดหน้าเว็บ

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

ใช้งานไม่ได้สำหรับฉันแบ่งสคริปต์อินไลน์ถัดไป ฉันใช้ jQuery 3.2.1 ร่วมกับส้อม jQuery อื่น ๆ ด้วย

ในการซ่อนเว็บไซต์ของฉันโหลดซ้อนทับฉันใช้สิ่งต่อไปนี้:

<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");
    }
});

เหมือนกันสำหรับ jQuery:

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

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





หมายเหตุ: - อย่าใช้มาร์กอัปด้านล่าง (เพราะมันเขียนทับการประกาศชนิดเดียวกันอื่น ๆ ):

document.onreadystatechange = ...

1

อย่างที่ Daniel พูดคุณสามารถใช้ document.onload ได้

กรอบงานจาวาสคริปต์ที่หลากหลาย hwoever (jQuery, Mootools เป็นต้น) ใช้เหตุการณ์ที่กำหนดเอง 'domready' ซึ่งฉันคิดว่าต้องมีประสิทธิภาพมากกว่า หากคุณกำลังพัฒนาด้วย javascript ฉันขอแนะนำให้ใช้ประโยชน์จากเฟรมเวิร์กพวกเขาจะเพิ่มประสิทธิภาพการทำงานของคุณอย่างหนาแน่น



0

asnycคุณลักษณะแนะนำให้ใช้ของฉันสำหรับแท็กสคริปต์ที่ช่วยให้คุณโหลดสคริปต์ภายนอกหลังจากโหลดหน้าเว็บ

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

7
ตามที่w3schools , ถ้า async เป็นปัจจุบัน: สคริปต์ที่จะดำเนินการถ่ายทอดสดกับส่วนที่เหลือของหน้า (สคริปต์ที่จะดำเนินการในขณะที่หน้ายังคงแยก) บางทีคุณอาจdeferต้องการที่จะพูดถึงอย่างเช่น @Daniel Price
jk7

0

ใช้ฟังก์ชั่น onload การดำเนินการด้วยตนเอง

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

2
คุณสามารถแทนที่onloadตัวจัดการอื่น ๆโดยใช้วิธีนี้ คุณควรเพิ่มผู้ฟังแทน
Leonid Dashko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.