Разница между 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а некоторые - оба, поэтому OP должен выбрать объект, соответствующий событию, которое они хотят обработать.
jfriend00

Оки Доки. Это то, что я обычно делаю тоже - именно поэтому я решил проверить это. Спасибо за ответ!
banzomaikaka

Поскольку событие 'click' доступно как в документе, так и в окне, и если мы регистрируем событие как в документе, так и в окне, то сначала срабатывает обработчик кликов документа, а затем окно. так что с этой точки зрения выбор документа лучше. jsfiddle.net/3LcVw
кодер

1
Другой пример: если вы добавите переходное addEventListener("keydown", event)отверстие windowдля телевизора Samsung, это не сработает. Но ты сделаешь то же самое с 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>

Перед выбором окна или документа для добавления списка событий необходимо отметить следующие моменты.

  1. Большинство событий одинаковы для windowили , documentно некоторые события нравится resize, и другие события , связанные с loading, unloadingиopening/closing все должны быть установлены в окне.
  2. Поскольку в окне есть документ, рекомендуется использовать документ для обработки (если он может обрабатываться), поскольку событие сначала попадет в документ.
  3. Internet Explorer не отвечает на многие события, зарегистрированные в окне, поэтому вам нужно будет использовать документ для регистрации события.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.