Разница между document.addEventListener и window.addEventListener?

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

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

В чем разница и что лучше использовать?


person Charlie    schedule 20.08.2012    source источник


Ответы (3)


document и window — это разные объекты, и у них разные события. Использование addEventListener() на них прослушивает события, предназначенные для другого объекта. Вы должны использовать тот, который действительно имеет интересующее вас событие.

Например, есть событие "resize" в объекте window, которого нет в объекте document.

Например, событие "readystatechange" относится только к объекту document.

Таким образом, в основном вам нужно знать, какой объект получает интересующее вас событие, и использовать .addEventListener() для этого конкретного объекта.

Вот интересная диаграмма, показывающая, какие типы объектов создают какие типы событий: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


Если вы прослушиваете распространяемое событие (например, событие щелчка), вы можете прослушивать это событие либо в объекте документа, либо в объекте окна. Единственное основное различие для распространяемых событий заключается во времени. Событие поразит объект document перед объектом window, так как он происходит первым в иерархии, но эта разница обычно несущественна, поэтому вы можете выбрать любой из них. Я считаю, что обычно лучше выбрать ближайший объект к источнику события, который соответствует вашим потребностям при обработке распространяемых событий. Это предполагает, что вы выбираете document вместо window, когда любой из них будет работать. Но я часто двигался еще ближе к источнику и использовал document.body или даже какой-то более близкий общий родитель в документе (если это возможно).

person jfriend00    schedule 20.08.2012
comment
Мне было любопытно всплыть к документу, но не к окну. Поэтому я проверил это здесь -› jsfiddle.net/k3qv9/1 Я что-то упустил или пузыри на самом деле происходят? - person João Paulo Macedo; 21.08.2012
comment
@JOPLOmacedo - перед вашим комментарием я удалил часть о всплывающих окнах, потому что не уверен, какие события всплывают в окне, а какие нет. Протокол, который я всегда видел, заключается в перехвате всплывающих событий на уровне документа в объекте document.body или объекте document, поэтому нет причин использовать window для всплывающих событий. В любом случае смысл моего ответа заключается в том, что некоторые события происходят только на window, а некоторые события - только на document, а некоторые - на обоих, поэтому OP должен выбрать объект, соответствующий событию, которое он хочет обработать. - person jfriend00; 21.08.2012
comment
Оки Доки. Это то, что я обычно делаю, именно поэтому я решил проверить это. Спасибо за ответ! - person João Paulo Macedo; 21.08.2012
comment
Поскольку событие «щелчок» доступно как в документе, так и в окне, и если мы зарегистрируем событие как в документе, так и в окне, то сначала срабатывает обработчик щелчка документа, а затем окно. так что с этой точки зрения выбор документа лучше. jsfiddle.net/3LcVw - person coder; 02.08.2014
comment
@MohammadSaeedKhan - Для событий, которые поднимаются до document и window (например, click), не имеет значения, на какое из них вы их поместите. Получит ли ваш обработчик событий щелчок на долю мс раньше одного по сравнению с другим, не будет иметь никакого значения. С точки зрения чистоты кода мне кажется более логичным, что обработчики событий, прикрепленные к window, должны быть событиями, которые происходят с самим окном (например, изменение размера). И тогда мне кажется более логичным, что обработчики событий в document — это то, что действительно происходит с документом (например, click или keyup). - person jfriend00; 03.08.2014
comment
@ jfriend00, поскольку документ является свойством (и объектом) глобального объекта окна, я думаю, что первое предложение может вводить в заблуждение (при условии, что это 2 совершенно разных объекта)? - person Vitaliy Terziev; 28.11.2015
comment
@vtz - это два совершенно разных объекта. Не имеет значения, если у одного из них есть ссылка на другое, хранящееся в свойстве. Это два совершенно разных объекта, и прослушивание событий на одном объекте не прослушивает события, которые происходят только на другом объекте. - person jfriend00; 28.11.2015
comment
как насчет document.body и document для добавления слушателей - person SuperUberDuper; 18.04.2016
comment
@SuperUberDuper - document и document.body являются разными элементами DOM и, следовательно, имеют разные события. Вы должны использовать элемент DOM с нужным вам событием. Для событий, которые всплывают, вы, вероятно, могли бы использовать любой из них, поскольку все, что всплывает до document.body, также будет всплывать до document. Я склонен выбирать ближайший к источнику элемент для всплывающих событий, что означает, что я бы выбрал document.body вместо document. - person jfriend00; 18.04.2016
comment
Другой пример: Если вы добавите addEventListener("keydown", event) через window для телевизора Samsung, то это не сработает. Но вы сделаете то же самое с document, тогда он будет. Также зависит от конкретного устройства, как оно вызывает пузырьковые события. - person Jakub Kubista; 20.01.2020

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

Из сети разработчиков Mozilla:

addEventListener() регистрирует один прослушиватель событий для одной цели. Целью события может быть отдельный элемент в документе, сам документ, окно или XMLHttpRequest.

Так что, пока вы можете рассчитывать на то, что ваша «цель» всегда будет там, единственная разница заключается в том, какие события вы слушаете, поэтому просто используйте свой любимый.

person Bryan Wolfford    schedule 20.08.2012
comment
Это не совсем так. На разных объектах происходят разные события. document и window не получают одни и те же события. Вы должны выбрать объект, который получает интересующее вас событие. Некоторые события могут идти как к document, так и к window, но не ко всем. - person jfriend00; 21.08.2012

Привязка 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 не отвечает на многие события, зарегистрированные в окне, поэтому вам нужно будет использовать документ для регистрации события.
person AConsumer    schedule 17.12.2019