ความแตกต่างระหว่าง document.addEventListener และ window.addEventListener


142

ในขณะที่ใช้ PhoneGap มีโค้ด JavaScript เริ่มต้นที่ใช้document.addEventListenerแต่ฉันมีรหัสของตัวเองซึ่งใช้window.addEventListener:

function onBodyLoad(){
    document.addEventListener("deviceready", onDeviceReady, false);
    document.addEventListener("touchmove", preventBehavior, false);
    window.addEventListener('shake', shakeEventDidOccur, false);
}

อะไรคือความแตกต่างและใช้แบบไหนดีกว่ากัน?

คำตอบ:


168

documentและwindowเป็นวัตถุที่แตกต่างกันและพวกเขามีเหตุการณ์บางอย่างที่แตกต่างกัน การใช้addEventListener()กับพวกเขาฟังเหตุการณ์ที่กำหนดไว้สำหรับวัตถุอื่น คุณควรใช้อันที่มีเหตุการณ์ที่คุณสนใจจริงๆ

ตัวอย่างเช่นมี"resize"เหตุการณ์บนwindowวัตถุที่ไม่ได้อยู่บนdocumentวัตถุ

ตัวอย่างเช่น"DOMContentLoaded"เหตุการณ์อยู่บนdocumentวัตถุเท่านั้น

โดยพื้นฐานแล้วคุณต้องรู้ว่าวัตถุใดได้รับเหตุการณ์ที่คุณสนใจและใช้.addEventListener()กับวัตถุนั้น ๆ

นี่คือแผนภูมิที่น่าสนใจที่แสดงให้เห็นว่าวัตถุประเภทใดสร้างเหตุการณ์ประเภทใด: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


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


1
ฉันอยากรู้เกี่ยวกับสิ่งที่ "เดือดปุด ๆ ไปที่เอกสาร ดังนั้นฉันจึงทดสอบที่นี่ -> jsfiddle.net/k3qv9/1ฉันขาดอะไรไปหรือเกิดฟองจริงหรือไม่?
banzomaikaka

1
@JOPLOmacedo - ก่อนความคิดเห็นของคุณฉันได้ลบส่วนที่เกี่ยวกับการฟองออกเนื่องจากฉันไม่แน่ใจว่าเหตุการณ์ใดที่ฟองสบู่ไปที่หน้าต่างและสิ่งที่ไม่ทำ โปรโตคอลที่ฉันเห็นมาตลอดคือการดักจับเหตุการณ์ที่มีฟองกว้างที่document.bodyวัตถุหรือdocumentวัตถุดังนั้นจึงไม่มีเหตุผลที่จะใช้windowสำหรับเหตุการณ์ฟองสบู่ ไม่ว่าในกรณีใดประเด็นของคำตอบของฉันคือบางเหตุการณ์เปิดอยู่เท่านั้นwindowและบางเหตุการณ์จะเปิดอยู่เท่านั้นและบางเหตุการณ์documentอยู่ในทั้งสองอย่างดังนั้น OP ควรเลือกวัตถุที่ตรงกับเหตุการณ์ที่พวกเขาต้องการจัดการ
jfriend00

Okey dokey นั่นคือสิ่งที่ฉันมักจะทำเช่นกัน - เหตุใดฉันจึงตัดสินใจทดสอบ ขอบคุณสำหรับคำตอบ!
banzomaikaka

เนื่องจากเหตุการณ์ 'คลิก' สามารถใช้ได้ทั้งในเอกสารและหน้าต่างและถ้าเราลงทะเบียนเหตุการณ์ทั้งในเอกสารและหน้าต่างจากนั้นตัวจัดการคลิกของการเริ่มทำงานของเอกสารจะขึ้นหน้าต่าง ดังนั้นสำหรับมุมมองนี้ทางเลือกของเอกสารจะดีกว่า jsfiddle.net/3LcVw
coder

1
อีกตัวอย่างหนึ่ง: หากคุณจะเพิ่มaddEventListener("keydown", event)ผ่านwindowSamsung TV กว่าจะใช้งานไม่ได้ แต่คุณจะทำสิ่งเดียวกันกับdocumentแล้วมันจะ ขึ้นอยู่กับอุปกรณ์เฉพาะว่ามันเรียกเหตุการณ์ฟองสบู่อย่างไร
Jakub Kubista

5

คุณจะพบว่าในจาวาสคริปต์มักจะมีหลายวิธีในการทำสิ่งเดียวกันหรือค้นหาข้อมูลเดียวกัน ในตัวอย่างของคุณคุณกำลังมองหาองค์ประกอบบางอย่างที่รับประกันว่าจะมีอยู่เสมอ windowและdocumentทั้งคู่พอดีกับใบเรียกเก็บเงิน (มีความแตกต่างเพียงเล็กน้อย)

จากmozilla dev network :

addEventListener () ลงทะเบียนตัวฟังเหตุการณ์เดียวในเป้าหมายเดียว เป้าหมายเหตุการณ์อาจเป็นองค์ประกอบเดียวในเอกสารเอกสารเองหน้าต่างหรือ XMLHttpRequest

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


5
นี่ไม่ใช่ความจริงโดยทั่วไป เหตุการณ์ที่แตกต่างกันเกิดขึ้นบนวัตถุที่แตกต่างกัน documentและwindowไม่ได้รับเหตุการณ์เดียวกัน คุณต้องเลือกวัตถุที่รับเหตุการณ์ที่คุณสนใจเหตุการณ์บางอย่างอาจไปที่ทั้งสองdocumentและwindowแต่ไม่ใช่ทั้งหมด
jfriend00

1

การwindowเชื่อมโยงหมายถึงวัตถุในตัวที่เบราว์เซอร์จัดเตรียมไว้ แสดงถึงหน้าต่างเบราว์เซอร์ที่มีไฟล์document. การเรียกaddEventListenerใช้เมธอดจะลงทะเบียนอาร์กิวเมนต์ที่สอง (ฟังก์ชันเรียกกลับ) ที่จะเรียกเมื่อใดก็ตามที่เหตุการณ์ที่อธิบายโดยอาร์กิวเมนต์แรกเกิดขึ้น

<p>Some paragraph.</p>
<script>
  window.addEventListener("click", () => {
    console.log("Test");
  });
</script>

ควรสังเกตจุดต่อไปนี้ก่อนเลือกหน้าต่างหรือเอกสารเพื่อ addEventListners

  1. ส่วนใหญ่ของเหตุการณ์ที่เกิดขึ้นเหมือนกันสำหรับwindowหรือdocumentแต่เหตุการณ์บางอย่างที่ชอบresizeและกิจกรรมอื่น ๆ ที่เกี่ยวข้องกับการloading, unloadingและopening/closingทุกคนควรจะตั้งอยู่บนหน้าต่าง
  2. เนื่องจากหน้าต่างมีเอกสารจึงควรใช้เอกสารเพื่อจัดการ (ถ้าสามารถจัดการได้) เนื่องจากเหตุการณ์จะตีเอกสารก่อน
  3. Internet Explorer ไม่ตอบสนองต่อเหตุการณ์มากมายที่ลงทะเบียนบนหน้าต่างดังนั้นคุณจะต้องใช้เอกสารสำหรับการลงทะเบียนเหตุการณ์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.