Різниця між document.addEventListener та window.addEventListener?


135

Під час використання PhoneGap у нього є якийсь код JavaScript за замовчуванням, який використовується document.addEventListener, але у мене є власний код, який використовує window.addEventListener:

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

У чому різниця і що краще використовувати?

Відповіді:


160

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або навіть якийсь ближчий спільний батьків у документі (якщо це можливо).


Мені було цікаво "штучка до документа, але не до вікна". Тож я перевірив це тут -> jsfiddle.net/k3qv9/1 Я щось пропускаю чи насправді булькання відбувається?
banzomaikaka

1
@JOPLOmacedo - перед вашим коментарем я видалив частину про барботаж, тому що я не знаю, які події пузируються у вікно, а які - ні. Протокол, який я завжди бачив, полягає в перехопленні подій у document.bodyоб'єкті або documentоб'єкті широких документообігу, тому немає ніяких причин використовувати windowдля барбованих подій. У будь-якому випадку, суть моєї відповіді полягає в тому, що деякі події тривають лише, windowа деякі події лише, documentа деякі - і те, і інше - і те, і інше, і ОП повинно обрати об'єкт, який відповідає події, з якою вони хочуть впоратись.
jfriend00

Окі докі. Ось що я зазвичай теж роблю - саме тому я вирішив перевірити це. Дякую за відповідь!
banzomaikaka

Оскільки подія "click" доступна як у документі, так і у вікні, і якщо ми реєструємо подію як у документі, так і у вікні, то спочатку оброблювач клацання документа запускається, а потім вікно. тому для цієї точки зору вибір документа краще. jsfiddle.net/3LcVw
кодер

1
Ще один приклад: Якщо ви додасте addEventListener("keydown", event)через windowдля Samsung TV, це не спрацює. Але ти зробиш те саме, що і documentтоді, і буде. Залежить також від конкретного пристрою, як він називає бульбашкові події.
Якуб Кубіста

4

Ви побачите, що в javascript зазвичай існує багато різних способів зробити те саме або знайти одну і ту ж інформацію. У вашому прикладі ви шукаєте якийсь елемент, який гарантовано завжди існує. windowі documentобидва підходять до векселя (лише з декількома різницями).

З мережі mozilla dev :

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 не відповідає на багато подій, зареєстрованих у вікні, тому вам потрібно буде використовувати документ для реєстрації події.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.