window.onload vs <body onload =“” />


227

อะไรคือความแตกต่างระหว่างwindow.onloadเหตุการณ์และonloadเหตุการณ์ของbodyแท็ก? ฉันจะใช้เมื่อใดและควรทำอย่างไรให้ถูกต้อง?


2
คุณควรใช้ "เพื่อล้อมรอบค่าแอตทริบิวต์
Sven Larson

คำตอบ:


218

window.onload = myOnloadFuncและ<body onload="myOnloadFunc();">มีวิธีการที่แตกต่างกันของการใช้เหตุการณ์เดียวกัน การใช้งานwindow.onloadนั้นไม่น่ารำคาญน้อยกว่า - ใช้ JavaScript ของคุณจาก HTML

ไลบรารี JavaScript ทั่วไป, Prototype, ExtJS, Dojo, JQuery, YUI ฯลฯ ให้การล้อมรอบที่ดีรอบเหตุการณ์ที่เกิดขึ้นเมื่อเอกสารถูกโหลด คุณสามารถฟังหน้าต่างเหตุการณ์เหตุการณ์โหลดและตอบสนองต่อเหตุการณ์นั้น แต่ onLoad จะไม่ทำงานจนกว่าจะดาวน์โหลดทรัพยากรทั้งหมดดังนั้นตัวจัดการเหตุการณ์ของคุณจะไม่ถูกดำเนินการจนกว่าจะมีการเรียกภาพขนาดใหญ่ครั้งสุดท้าย ในบางกรณีนั่นคือสิ่งที่คุณต้องการอย่างแน่นอนในบางกรณีคุณอาจพบว่าการฟังเมื่อ DOM พร้อมแล้วก็เหมาะสมกว่า - เหตุการณ์นี้คล้ายกับ onLoad แต่เริ่มทำงานโดยไม่ต้องรอรูปภาพและอื่น ๆ เพื่อดาวน์โหลด


57
อย่างไรก็ตามควรสังเกตว่ามีความแตกต่าง เหตุการณ์ inload onload กำลังจะถูกเรียกmyOnloadFunc()ในบริบทโกลบอล ( thisจะอ้างถึงwindow) การตั้งค่าผ่าน javascript จะทำให้มันทำงานในบริบทขององค์ประกอบ ( thisหมายถึงองค์ประกอบที่เหตุการณ์ถูกเรียกใช้) ในกรณีนี้มันจะไม่สร้างความแตกต่าง แต่มันจะมีองค์ประกอบอื่น ๆ
mowwwalker

1
@Walkerneo: ใช่แน่นอนน่าสังเกต แน่นอนว่าการใช้ไลบรารี JS สามารถแทนที่วัตถุที่thisอ้างถึงได้หากต้องการ
Richard Turner

@RichardTurner คุณไม่จำเป็นต้องใช้ไลบรารีเพื่อเปลี่ยนการเชื่อมโยงบริบท การโทรแบบ. ผูก () แบบง่ายๆนั้นทำได้
Kloar

@Kloar คุณสามารถวันนี้ใช่ แต่คุณต้อง MSIE9 + สำหรับ MSIE รุ่นเก่าซึ่งพบได้บ่อยกว่าเมื่อฉันตอบคุณต้องมีโพลีฟิล
Richard Turner

33

ไม่มีความแตกต่าง แต่คุณไม่ควรใช้อย่างใดอย่างหนึ่ง

ในเบราว์เซอร์จำนวนมากwindow.onloadเหตุการณ์จะไม่ถูกเรียกใช้จนกว่าจะโหลดรูปภาพทั้งหมดซึ่งไม่ใช่สิ่งที่คุณต้องการ เบราว์เซอร์ที่ใช้มาตรฐานมีเหตุการณ์ที่เรียกว่าDOMContentLoadedfires ก่อนหน้านี้ แต่ IE ไม่รองรับ (ในขณะที่เขียนคำตอบนี้) ฉันขอแนะนำให้ใช้ไลบรารี javascript ซึ่งรองรับคุณสมบัติข้ามเบราว์เซอร์ DOMContentLoaded หรือค้นหาฟังก์ชั่นที่เขียนได้ดีที่คุณสามารถใช้ได้ jQuery's $(document).ready()เป็นตัวอย่างที่ดี


53
คำถามจากอนาคต ... จะเกิดอะไรขึ้นถ้าไม่มี jQuery
ซิด

54
คำถามจากปัจจุบัน .. จะเกิดอะไรขึ้นถ้า jQuery เกินความจำเป็นสำหรับโครงการในมือ? (ไม่เคาะ jQuery ใช้มันด้วยตัวเองบางครั้งต้องการเพียงฟีเจอร์เดียวเท่านั้นที่ออกจากห้องสมุด .. )
Bradmage

14
เมื่อคุณพูดว่า "ไม่รองรับ IE" นั่นเป็นความจริงสากลหรือเป็นจริงสำหรับ IE บางรุ่นเท่านั้น? เนื่องจากมีการเปลี่ยนแปลงมากมายในโลกของเบราว์เซอร์ตั้งแต่ที่คุณเขียนคำตอบนี้อาจถึงเวลาที่จะอัพเดตคำตอบนี้หรือไม่
ไบรอัน Oakley

8
ขณะนี้ DOMContentLoaded รองรับ IE9 ขึ้นไป: developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Adam

6
การรายงานจากอนาคต DOMContentLoaded ได้รับการสนับสนุนในขณะนี้โดยเบราว์เซอร์หลักทั้งหมด: caniuse.com/#feat=domcontentloaded
Jose Gómez

21

window.onloadสามารถทำงานได้โดยไม่มีร่างกาย สร้างหน้าเว็บที่มีแท็กสคริปต์เท่านั้นและเปิดในเบราว์เซอร์ หน้าไม่มีเนื้อหาใด ๆ แต่ก็ยังใช้งานได้ ..

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

6
HTML ที่ไม่มีแท็กเนื้อหาจะไม่ถูกต้องหากคุณเพิ่มเนื้อหาจริง (ซึ่งควรอยู่ในแท็กเนื้อหา) แท็กสคริปต์ของคุณไม่มีประเภท อย่าพึ่งพาเบราว์เซอร์ที่แก้ไขโค้ดที่ไม่ได้มาตรฐานของคุณ! (เนื่องจากเบราว์เซอร์อาจทำเช่นนั้นแตกต่างกันหรือไม่เลยในอดีตหรืออนาคต)
Kissaki

4
@Kissaki: HTML มาตรฐานไม่จำเป็นต้องมีแท็กเนื้อหาเลย!
Robert Siemer

5
xhtml1 ระบุ<!ELEMENT html (head, body)>[1] - และ html401 ระบุ<!ELEMENT HTML O O (%html.content;)ด้วย<!ENTITY % html.content "HEAD, BODY">เช่นกัน [2] html51 ระบุA head element followed by a body element.เนื้อหา html เช่นกัน [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#the -html-element - ดังนั้นฉันเดาว่ามาตรฐาน HTML ทั่วไป / ที่ใช้งานอยู่ทั้งหมดนั้นต้องใช้แท็กเนื้อหา :)
Kissaki

1
@Kissaki นั่นคือ XHTML ไม่ใช่ HTML HTML อนุญาตให้ละเว้นแท็กของแท็กเริ่มต้นและแท็กเนื้อหารวมถึงการละเว้น HTML และแท็กส่วนหัวตาม SGML DTD w3.org/TR/html401/struct/global.html#edef-BODY Start tag: optional, End tag: optional
OdraEncoded

1
@Kissaki: html5 ไม่ต้องการประเภทสคริปต์อีกต่อไป (ถ้าเป็น javascript) คุณเหมาะกับเวอร์ชันก่อนหน้า
ทำเครื่องหมาย

10

ฉันชอบโดยทั่วไปจะไม่ใช้<body onload=""> กิจกรรม ฉันคิดว่าการแยกพฤติกรรมออกจากเนื้อหาให้มากที่สุดเท่าที่จะทำได้

ที่กล่าวว่ามีโอกาส (มักจะหายากสำหรับฉัน) ที่การใช้ตัวถังรถสามารถเพิ่มความเร็วเล็กน้อย

ฉันชอบที่จะใช้ Prototype ดังนั้นโดยทั่วไปฉันจะใส่อะไรแบบนี้ใน<headหน้าของฉัน:

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

หรือ

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

ข้างต้นเป็นเทคนิคที่ผมได้เรียนรู้ที่นี่ ฉันชื่นชอบแนวคิดของการแนบตัวจัดการเหตุการณ์นอก HTML

(แก้ไขเพื่อแก้ไขการสะกดผิดในรหัส)


มันจะเร็วขึ้นในโอกาสใดและทำไม?
Kissaki

คำตอบนี้ดูเหมือนเป็นอัตนัยกับ“ ฉัน” ทั้งหมด (“ ฉันชอบ”,“ ฉันคิด”) ถ้าไม่มีข้อเท็จจริงและวัตถุประสงค์ใด ๆ ที่ตรวจสอบได้สนับสนุนความประทับใจนั้น
Kissaki

1
ฉันจะตอบคำถามนี้ด้วยเม็ดเกลือเพราะมันโพสต์เมื่อ 6 ปีที่แล้ว คุณมีมากกว่ายินดีที่จะอัปเดตหรือโพสต์คำตอบที่ดีขึ้นของคุณเอง
Mark Biek

7

'คำตอบเชิงอัตวิสัยมากมายสำหรับคำถามวัตถุประสงค์ JavaScript "ไม่สร้างความรำคาญ" เป็นความเชื่อโชคลางเหมือนกฎเดิมที่จะไม่ใช้ gotos เขียนโค้ดในลักษณะที่ช่วยให้คุณบรรลุเป้าหมายได้อย่างน่าเชื่อถือไม่ใช่ตามความเชื่อทางศาสนาของใครบางคน

ทุกคนที่พบ:

 <body onload="body_onload();">

การที่จะทำให้เสียสมาธิมากเกินไปคือการทำท่ามากเกินไปและไม่ได้จัดลำดับความสำคัญตรง

ปกติแล้วฉันจะใส่รหัส JavaScript ในไฟล์. js แยกกัน แต่ฉันไม่พบอะไรยุ่งยากเกี่ยวกับการเชื่อมโยงตัวจัดการเหตุการณ์ใน HTML ซึ่งเป็น HTML ที่ถูกต้องตามวิธี


39
มีเหตุผลที่ดีสำหรับการเขียนจาวาสคริปต์ที่ไม่สร้างความรำคาญ สมมติว่าคุณมีเว็บแอปที่มี 100 หน้าและคุณใช้เมธอด <body onload = "body_onload ();"> แทนที่จะใส่ไว้ในไฟล์จาวาสคริปต์ที่รวมอยู่ในทุกหน้า จากนั้นลองนึกภาพคุณจำเป็นต้องเปลี่ยนชื่อของฟังก์ชันนั้นด้วยเหตุผลบางอย่าง การวางเหตุการณ์ในไฟล์จาวาสคริปต์ที่รวมอยู่ 1) ทำให้การเปลี่ยนแปลงง่ายขึ้นอย่างมากมายและ 2) บันทึกทรัพยากรของเซิร์ฟเวอร์เนื่องจากไฟล์จาวาสคริปต์สามารถถูกแคชได้เป็นเวลาหนึ่งปี (บนเซิร์ฟเวอร์ที่กำหนดค่าอย่างเหมาะสม) แทนที่จะดาวน์โหลดรหัสเดียวกันซ้ำแล้วซ้ำอีก
Andrew Ensley

21
ดังนั้นเพราะคุณไม่ต้องเรียนรู้ว่าทำไมมีอะไรแนะนำให้คุณติดป้ายคำแนะนำ "ความเชื่อทางศาสนาที่ทันสมัย"?
hallvors

6
คำถามคือ "ความแตกต่างระหว่างสองวิธีนี้คืออะไร" พร้อมกับการขอคำแนะนำที่ดีกว่า คำตอบของคุณตอบคำถามนั้นอย่างไร
Richard Turner

1
สถานการณ์ใด ๆ ที่คุณสร้างโซลูชันแบบแยกส่วนในที่เดียวที่สามารถนำไปใช้กับไฟล์จำนวนมากนั้นดีกว่าการเพิ่มโค้ดลงในไฟล์จำนวนมากแต่ละไฟล์ มันจะดีกว่าสำหรับเวลาสร้างดั้งเดิมรหัสวัตถุประสงค์ขององค์กรเพื่อให้สามารถอ่านได้และสำหรับการแก้ไขในอนาคต มันไม่ได้เป็นเทรนด์จริงๆแล้วมันเป็นแนวคิดที่เก่ากว่าที่มีอยู่ในภาษาอย่าง java และ c ++ ที่โปรแกรมเมอร์เว็บตอนนี้ยอมรับว่าเป็นวิธีที่ดีกว่าในการเขียนโค้ด
Jimbo Jonny

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

4

window.onload- ถูกเรียกหลังจาก DOM, ไฟล์ JS, รูปภาพ, Iframes, ส่วนขยายและอื่น ๆ ทั้งหมดโหลดอย่างสมบูรณ์ นี่เท่ากับ $ (หน้าต่าง). load (function () {});

body onload=""- เรียกว่าเมื่อโหลด DOM แล้ว นี่เท่ากับ $ (เอกสาร). ready (function () {});


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

1
@crempp มีองค์ประกอบของร่างกายและคุณสมบัติสากลดังนั้นฉันจะบอกว่านี่ไม่เป็นความจริง แต่คุณสามารถทดสอบนี้ด้วยตัวเองดูjsbin.com/OmiViPAJ/1/edit ที่นั่นคุณสามารถเห็นเหตุการณ์ภาพโหลดถูกยิงก่อนเหตุการณ์เหตุการณ์โหลดเนื้อหา
Olaf Dietsche

2
คำตอบนี้ขัดแย้งกับคนอื่น ๆ ; คุณสามารถให้แหล่งที่มาหรือไม่?
Jimmy Breck-McKye

2
api.jquery.com/readyเอกสาร jQuery พูดว่า: "โดยทั่วไปแล้ว. เมธอด. Ready () จะไม่เข้ากันกับแอตทริบิวต์ <body onload =" ">" ฉันคิดว่าใน jQuery ใกล้กับ body.onload $ (window) .load (.. ) แต่ฉันคิดว่าพวกเขายังคงแตกต่างกัน
ccsakuweb

2
คำตอบนี้ผิดอย่างสมบูรณ์และไม่ควรมีการโหวต ในความเป็นจริงคำตอบประเภทนี้โดยทั่วไปอ้างว่าเป็นหนึ่งในความเข้าใจผิดที่ใหญ่ที่สุดเกี่ยวreadyกับonloadเหตุการณ์vs loadไฟไหม้หลังจากโหลดเอกสารทั้งหมดรวมถึงสคริปต์ภาพและสไตล์ทั้งหมด DOMContentLoadedไฟไหม้หลังจากต้นไม้ DOM ได้รับการสร้างขึ้น แต่ก่อนที่ภาพ ฯลฯDOMContentLoadedที่มีความเท่าเทียมกันที่จะไม่document.ready load
rism

2

นอกจากนี้ไม่มีความแตกต่าง ...

ดังนั้นโดยพื้นฐานแล้วคุณสามารถใช้ทั้งคู่ (ทีละครั้ง! -)

แต่เพื่อความสะดวกในการอ่านและเพื่อความสะอาดของรหัส html ฉันมักจะชอบ window.onload! o]


1

ถ้าคุณกำลังพยายามที่จะเขียนรหัส JS สร้างความรำคาญ (และคุณควรจะเป็น) <body onload="">แล้วคุณไม่ควรใช้

ฉันเข้าใจว่าเบราว์เซอร์ที่แตกต่างกันจัดการทั้งสองนี้แตกต่างกันเล็กน้อย แต่ทำงานเหมือนกัน ในเบราว์เซอร์ส่วนใหญ่หากคุณกำหนดทั้งสองจะถูกละเว้น


1

ลองนึกถึงการโหลดเช่นเดียวกับคุณลักษณะอื่น ๆ ตัวอย่างเช่นในกล่องอินพุตคุณสามารถใส่:

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

หรือคุณสามารถโทร:

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

แอ็ตทริบิวต์ onload ทำงานในลักษณะเดียวกันยกเว้นว่าจะรับฟังก์ชั่นเป็นค่าแทนที่จะเป็นสตริงเช่นเดียวกับแอตทริบิวต์ที่ทำ นอกจากนี้ยังอธิบายว่าทำไมคุณสามารถ "ใช้เพียงหนึ่งในนั้น" - การเรียก window.onload กำหนดค่าของแอตทริบิวต์ onload ใหม่สำหรับแท็ก body

นอกจากนี้เช่นเดียวกับคนอื่น ๆ ที่กำลังพูดอยู่มักจะเป็นเรื่องง่ายที่จะรักษาสไตล์และจาวาสคริปต์แยกจากเนื้อหาของหน้าซึ่งเป็นสาเหตุที่คนส่วนใหญ่แนะนำให้ใช้ window.onload หรือฟังก์ชั่นที่พร้อมของ jQuery


1

<body onload = ""> ควรแทนที่ window.onload

ด้วย <body onload = ""> document.body.onload อาจเป็นโมฆะไม่ได้กำหนดหรือฟังก์ชั่นขึ้นอยู่กับเบราว์เซอร์ (แม้ว่า getAttribute ("onload") ควรจะค่อนข้างสอดคล้องกันเพื่อให้ร่างกายของฟังก์ชั่นที่ไม่ระบุชื่อเป็นสตริง) . ด้วย window.onload เมื่อคุณกำหนดฟังก์ชั่นให้กับมัน window.onload จะเป็นฟังก์ชั่นที่สอดคล้องกันในเบราว์เซอร์ หากสิ่งนั้นสำคัญสำหรับคุณให้ใช้ window.onload

window.onload ดีกว่าสำหรับการแยก JS ออกจากเนื้อหาของคุณ ไม่มีเหตุผลมากนักที่จะใช้ <body onload = ""> อย่างไรก็ตามเมื่อคุณสามารถใช้ window.onload ได้

ใน Opera เป้าหมายเหตุการณ์สำหรับ window.onload และ <body onload = ""> (และแม้กระทั่ง window.addEventListener ("load", func, false)) จะเป็นหน้าต่างแทนเอกสารเช่นใน Safari และ Firefox แต่ 'นี่' จะเป็นหน้าต่างข้ามเบราว์เซอร์

สิ่งนี้หมายความว่าเมื่อมันเป็นเรื่องสำคัญคุณควรห่อสิ่งที่หยาบและทำสิ่งที่สอดคล้องกันหรือใช้ห้องสมุดที่ทำเพื่อคุณ


0

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

เฟรมเวิร์ก JS ใด ๆ จะมีวิธีการข้ามเบราว์เซอร์สำหรับตัวจัดการเหตุการณ์


0

เป็นมาตรฐานที่ยอมรับได้ในการแยกเนื้อหาเค้าโครงและพฤติกรรม ดังนั้น window.onload () จะเหมาะสมกว่าที่จะใช้มากกว่า<body onload="">ทั้งสองทำงานเดียวกัน


0

ขออภัยสำหรับการเกิดใหม่ของหัวข้อนี้อีกครั้งหลังจากนั้นอีก 3 ปีของการนอนหลับ แต่บางทีฉันได้พบในที่สุดผลประโยชน์เถียงไม่ได้ของมากกว่าwindow.onload=fn1; <body onload="fn1()">มันเกี่ยวข้องกับโมดูล JSหรือโมดูลES : เมื่อonloadตัวจัดการของคุณอยู่ในไฟล์ "คลาสสิค" JS (เช่นที่เรียกว่าไม่มี<script type="module" … >วิธีใดเป็นไปได้เมื่อonloadตัวจัดการของคุณอยู่ในไฟล์ "โมดูล" JS (เช่นเรียกด้วย<script type="module" … >) <body onload="fn1()">จะล้มเหลวด้วย "fn1 () ไม่ได้กำหนดไว้ "ข้อผิดพลาดเหตุผลอาจเป็นได้ว่าโมดูล ES ไม่ได้โหลดก่อนที่จะแยกวิเคราะห์ HTML ... แต่เป็นเพียงการคาดเดาของฉันอย่างไรก็ตามwindow.onload=fn1;ทำงานได้อย่างสมบูรณ์กับโมดูล ...

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