เรียกใช้ฟังก์ชันหลังจากโหลดหน้าเสร็จสมบูรณ์


121

ฉันใช้รหัสต่อไปนี้เพื่อดำเนินการคำสั่งหลังจากโหลดหน้า

 <script type="text/javascript">
    window.onload = function () { 

        newInvite();
        document.ag.src="b.jpg";
    }
</script>

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


1
คุณช่วยเพิ่มการสาธิตในJSFiddle.net ได้ไหม
Some Guy

2
คุณสามารถใช้ jQuery ได้หรือไม่? ถ้าเป็นเช่นนั้นลอง$(window).load()
Matt Hintzke

ใช่คุณช่วยอธิบายได้ไหมว่าอะไรทำงานไม่ถูกต้อง คุณได้รับข้อผิดพลาดหรือบางทีคุณอาจเรียกใช้alertฟังก์ชันก่อนที่หน้าต่างจะวาดใหม่ (ทำให้ดูเหมือนถูกเรียกก่อนโหลด) รหัสดูดีและการบังคับให้ผู้ใช้ดาวน์โหลดไลบรารีขนาดใหญ่อาจไม่สามารถแก้ไขปัญหานี้หรือทำให้ง่ายต่อการวินิจฉัย
Jeffrey Sweeney


เมื่อฉันบอกว่ามันไม่ทำงานฉันหมายถึงฟังก์ชั่นจะทำงานมากกว่าแม้ว่าจะโหลดบางภาพ
Neeraj Kumar

คำตอบ:


166

สิ่งนี้อาจเหมาะกับคุณ:

document.addEventListener('DOMContentLoaded', function() {
   // your code here
}, false);

หรือถ้าคุณสบายใจด้วย jquery

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

$(document).ready()เริ่มทำงานบน DOMContentLoaded แต่เหตุการณ์นี้ไม่ได้ถูกเริ่มทำงานอย่างสม่ำเสมอระหว่างเบราว์เซอร์ นี่คือเหตุผลที่ jQuery ส่วนใหญ่อาจใช้วิธีแก้ปัญหาที่หนักหน่วงเพื่อรองรับเบราว์เซอร์ทั้งหมด และนี่จะทำให้การจำลองพฤติกรรมโดยใช้ Javascript ธรรมดาเป็นเรื่องยากมาก (แต่ไม่ใช่เรื่องที่เป็นไปไม่ได้แน่นอน)

ตามที่ Jeffrey Sweeney และ J Torres แนะนำฉันคิดว่ามันดีกว่าที่จะมีsetTimeoutฟังก์ชั่นก่อนที่จะเริ่มใช้งานฟังก์ชันดังต่อไปนี้:

setTimeout(function(){
 //your code here
}, 3000);

12
jQuery readyจะไม่ทำตามที่ OP ร้องขอ readyเริ่มทำงานเมื่อ DOM โหลดไม่ใช่หลังจากองค์ประกอบโหลด loadจะเริ่มทำงานหลังจากที่องค์ประกอบเสร็จสิ้นการโหลด / การแสดงผล
Jaime Torres

ดูเหมือนว่า OP ต้องการให้โหลดองค์ประกอบทั้งหมดทั้งหมดไม่ใช่แค่ HTML
Jeffrey Sweeney

3
@shreedhar หรือเขาสามารถใช้เครื่องมือที่เหมาะสมกับงาน ( load)
Jaime Torres

14
setTimeoutเป็นความคิดที่ไม่ดี ขึ้นอยู่กับการโหลดหน้าเว็บน้อยกว่า 3 วินาที (หรือnวินาทีขึ้นอยู่กับค่าที่คุณเลือก) หากการโหลดใช้เวลานานกว่านั้นจะไม่ทำงานและหากโหลดหน้าเว็บเร็วขึ้นก็จะต้องรอโดยไม่มีเหตุผล
JJJ

1
@ChristianMatthew มันuseCapture ถ้าเป็นจริง useCapture บ่งชี้ว่าผู้ใช้ต้องการเริ่มการจับภาพ หลังจากเริ่มการบันทึกเหตุการณ์ทั้งหมดในประเภทที่ระบุจะถูกส่งไปยังผู้ฟังที่ลงทะเบียนก่อนที่จะถูกส่งไปยัง EventTargets ใด ๆ ที่อยู่ข้างใต้ในโครงสร้าง DOM เหตุการณ์ที่เดือดพล่านขึ้นไปตามต้นไม้จะไม่ทำให้ผู้ฟังถูกกำหนดให้ใช้การจับภาพ ดูเหตุการณ์ DOM ระดับ 3สำหรับคำอธิบายโดยละเอียด
Shreedhar

52

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
รองรับเบราว์เซอร์ข้ามหรือไม่
bluejayke

คำตอบนี้ดีกว่าข้ออื่น ๆ มาก +1
Xydez

ดีมาก! ขอบคุณ
Farzin Kanzi

34

หากคุณสามารถใช้ jQuery ดูที่โหลด จากนั้นคุณสามารถตั้งค่าฟังก์ชันให้ทำงานหลังจากที่องค์ประกอบของคุณโหลดเสร็จสิ้น

ตัวอย่างเช่นพิจารณาหน้าที่มีรูปภาพง่ายๆ:

<img src="book.png" alt="Book" id="book" />

ตัวจัดการเหตุการณ์สามารถเชื่อมโยงกับรูปภาพ:

$('#book').load(function() {
  // Handler for .load() called.
});

หากคุณต้องการโหลดองค์ประกอบทั้งหมดในหน้าต่างปัจจุบันคุณสามารถใช้

$(window).load(function () {
  // run code
});

1
loadวิธีjQuery ไม่เพียงผูกฟังก์ชันกับเหตุการณ์โหลดโดยใช้ Javascript หรือไม่? สิ่งนี้จะแตกต่างจากที่ OP ทำอยู่แล้วอย่างไร?
Alex Kalicki

@AlexKalicki AFAIK มันจะไม่แตกต่างกันยกเว้นว่า jQuery อาจใช้addEventListenerแทนที่จะผูกonloadคุณสมบัติDOM0
Alnitak

@AlexKalicki ฉันไม่สามารถพูดได้ว่ามันใช้ฟังก์ชันการทำงานเดียวกันทุกประการ แต่ตามเอกสารประกอบ jQuery มั่นใจว่าองค์ประกอบทั้งหมดรวมถึงรูปภาพจะถูกโหลดก่อนที่จะเริ่มทำงาน ฉันมักจะเชื่อว่าจะมีตรรกะเพิ่มเติมหากเป็นกรณีนี้และฉันไม่มีเหตุผลที่จะปฏิเสธที่จะเชื่อเอกสารแม้ว่าฉันจะไม่เคยพบปัญหาเดียวกันกับที่ OP รายงาน
Jaime Torres

4
ตั้งแต่ JQuery v1.8, .load เลิกใช้แล้ว ที่มา
Adonis K. Kakoulidis

1
ทางออกที่ดีที่สุดสำหรับคำถามนี้
Roberto Sepúlveda Bravo

29

ฉันสับสนเล็กน้อยว่าคุณหมายถึงอะไรเมื่อโหลดหน้าเสร็จแล้ว "DOM Load" หรือ "Content Load" กันแน่? ในการโหลดหน้า html สามารถเริ่มเหตุการณ์หลังจากเหตุการณ์สองประเภท

  1. โหลด DOM: ซึ่งทำให้แน่ใจว่าโครงสร้าง DOM ทั้งหมดที่โหลดเริ่มต้นจนจบ แต่อย่าให้แน่ใจว่าโหลดเนื้อหาอ้างอิง สมมติว่าคุณเพิ่มรูปภาพโดยimgแท็กดังนั้นเหตุการณ์นี้ทำให้แน่ใจว่าทุกภาพที่imgโหลด แต่ไม่มีภาพที่โหลดอย่างถูกต้องหรือไม่ หากต้องการรับกิจกรรมนี้คุณควรเขียนดังนี้:

    document.addEventListener('DOMContentLoaded', function() {
       // your code here
    }, false);

    หรือใช้ jQuery:

    $(document).ready(function(){
    // your code
    });
  2. หลัง DOM และการโหลดเนื้อหา: ซึ่งระบุการโหลด DOM และเนื้อหาด้วย เพื่อให้แน่ใจว่าไม่เพียง แต่imgแท็กเท่านั้น แต่ยังช่วยให้แน่ใจว่ามีการโหลดรูปภาพหรือเนื้อหาอื่น ๆ ทั้งหมด หากต้องการรับกิจกรรมนี้คุณควรเขียนดังนี้:

    window.addEventListener('load', function() {...})

    หรือใช้ jQuery:

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

2
นี่เป็นคำตอบเดียวที่ให้โซลูชันที่ไม่ใช่ jQuery สำหรับ OP พร้อมคำอธิบายที่ชัดเจน
Velojet

@Hanif DOMContentLoadedตัวจัดการเหตุการณ์ดูเหมือนจะไม่ทำอะไรให้ฉัน แต่loadทำ
Brandon Benefield

1
สองตัวอย่างสุดท้ายไม่จำเป็นต้องมีเครื่องหมายอัฒภาคที่ท้ายบรรทัดหรือไม่?
R.Navega

11

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

<body onload="callFunction();">
....
</body>

7

ด้วยวิธีนี้คุณสามารถจัดการกับทั้งสองกรณีได้ - หากโหลดเพจแล้วหรือไม่:

document.onreadystatechange = function(){
    if (document.readyState === "complete") {
       myFunction();
    }
    else {
       window.onload = function () {
          myFunction();
       };
    };
}

3

หรือคุณสามารถลองด้านล่าง

$(window).bind("load", function() { 
// code here });

สิ่งนี้ใช้ได้ในทุกกรณี สิ่งนี้จะทริกเกอร์เฉพาะเมื่อโหลดทั้งหน้า


3

คุณเป็นทางออกที่ดีที่สุดเท่าที่ฉันรู้คือใช้

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

คำตอบ # 1 ของการใช้DOMContentLoadedเหตุการณ์คือการถอยหลังเนื่องจาก DOM จะโหลดก่อนที่เนื้อหาทั้งหมดจะโหลด

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

สำหรับreadystatechangeมันจะเริ่มทำงานเมื่อใดก็ตามที่มีreadyStateการเปลี่ยนแปลงซึ่งตามMDNจะยังคงอยู่ก่อนloadเหตุการณ์

สมบูรณ์

สถานะบ่งชี้ว่าเหตุการณ์โหลดกำลังจะเริ่มทำงาน


2
window.onload = () => {
  // run in onload
  setTimeout(() => {
    // onload finished.
    // and execute some code here like stat performance.
  }, 10)
}

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

@yivi ถ้านั่นไม่ใช่ข้อความอัตโนมัติ: มันค่อนข้างชัดเจนสำหรับทุกคนว่ารหัสนั้นหมายถึงอะไรโดยเฉพาะอย่างยิ่งเมื่อมีความคิดเห็นในรหัส ..
bluejayke

1

หากคุณไม่ได้ใช้เฟรมเวิร์ก JS ใด ๆ โปรเจ็กต์นี้เป็นวิธีที่ดีที่สุดในการรับสถานะพร้อมใช้งานของ Dom พร้อมกับความเข้ากันได้กับเบราว์เซอร์ข้าม

https://github.com/ded/domready/blob/master/ready.js


1

หากคุณใช้ jQuery อยู่แล้วคุณสามารถลองสิ่งนี้:

$(window).bind("load", function() {
   // code here
});

4
ไร้ประโยชน์โดยไม่มีคำอธิบาย
Daniel W.

1

ฉันบอกคุณได้ว่าคำตอบที่ดีที่สุดที่ฉันพบคือการใส่สคริปต์ "ไดรเวอร์" ไว้หลัง</body>คำสั่ง เป็นวิธีที่ง่ายที่สุดและอาจเป็นสากลมากกว่าวิธีแก้ปัญหาข้างต้น

แผน: บนหน้าของฉันคือตาราง ฉันเขียนหน้าด้วยตารางไปยังเบราว์เซอร์แล้วจัดเรียงด้วย JS ผู้ใช้สามารถใช้โดยคลิกที่ส่วนหัวของคอลัมน์

หลังจากตารางสิ้นสุด</tbody>คำสั่งและเนื้อหาสิ้นสุดลงฉันใช้บรรทัดต่อไปนี้เพื่อเรียกใช้การเรียงลำดับ JS เพื่อจัดเรียงตารางตามคอลัมน์ 3 ฉันได้รับสคริปต์การเรียงลำดับออกจากเว็บดังนั้นจึงไม่ถูกสร้างซ้ำที่นี่ อย่างน้อยปีถัดไปคุณสามารถดูนี้ในการดำเนินงานรวมทั้ง JS static29.ILikeTheInternet.comที่ คลิก "ที่นี่" ที่ด้านล่างของหน้า ซึ่งจะแสดงหน้าอื่นพร้อมตารางและสคริปต์ คุณสามารถเห็นมันวางข้อมูลแล้วเรียงลำดับอย่างรวดเร็ว ฉันต้องเร่งความเร็วเล็กน้อย แต่ตอนนี้พื้นฐานอยู่ที่นั่นแล้ว

</tbody></body><script type='text/javascript'>sortNum(3);</script></html>

MakerMikey


0

ลองใช้jQueryนี้:

$(function() {
 // Handler for .ready() called.
});

1
jQuery readyจะไม่ทำตามที่ OP ร้องขอ readyเริ่มทำงานเมื่อ DOM โหลดไม่ใช่หลังจากองค์ประกอบโหลด loadจะเริ่มทำงานหลังจากที่องค์ประกอบเสร็จสิ้นการโหลด / การแสดงผล
Jaime Torres

0

เรียกใช้ฟังก์ชันหลังจากหมดเวลาตั้งค่าการโหลดหน้าเสร็จสมบูรณ์

setTimeout(function() {
   var val = $('.GridStyle tr:nth-child(2) td:nth-child(4)').text();
	for(var i, j = 0; i = ddl2.options[j]; j++) {
		if(i.text == val) {      
			ddl2.selectedIndex = i.index;
			break;
		}
	} 
}, 1000);


0

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

function getDocReadyPromise()
{
  function promiseDocReady(resolve)
  {
    function checkDocReady()
    {
      if (document.readyState === "complete")
      {
        clearInterval(intervalDocReady);
        resolve();
      }
    }
    var intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

แน่นอนถ้าคุณไม่ต้องรองรับ IE:

const getDocReadyPromise = () =>
{
  const promiseDocReady = (resolve) =>
  {
    const checkDocReady = () =>
      ((document.readyState === "complete") && (clearInterval(intervalDocReady) || resolve()));
    let intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

ด้วยฟังก์ชั่นดังกล่าวคุณสามารถทำสิ่งต่อไปนี้:

getDocReadyPromise().then(whatIveBeenWaitingToDo);

-1

ฉันใช้ส่วนประกอบของเว็บเพื่อให้เหมาะกับฉัน:

document.addEventListener('WebComponentsReady', function() {
       document.querySelector('your-element').show();
});

-3

ใส่สคริปต์ของคุณหลังจากแท็กเนื้อหาเสร็จสิ้น ... มันได้ผล ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.