¿Diferencia entre document.addEventListener y window.addEventListener?

135

Mientras uso PhoneGap, tiene un código predeterminado de JavaScript que usa document.addEventListener, pero tengo mi propio código que usa window.addEventListener:

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

¿Cuál es la diferencia y cuál es mejor usar?

Charlie
fuente

Respuestas:

160

El documenty windowson objetos diferentes y tienen algunos eventos diferentes. Usar addEventListener()en ellos escucha eventos destinados a un objeto diferente. Debe usar el que realmente tiene el evento que le interesa.

Por ejemplo, hay un "resize"evento en el windowobjeto que no está en el documentobjeto.

Por ejemplo, el "DOMContentLoaded"evento es solo en el documentobjeto.

Básicamente, debe saber qué objeto recibe el evento que le interesa y utilizarlo .addEventListener()en ese objeto en particular.

Aquí hay un gráfico interesante que muestra qué tipos de objetos crean qué tipos de eventos: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


Si está escuchando un evento propagado (como el evento de clic), puede escuchar ese evento en el objeto del documento o en el objeto de la ventana. La única diferencia principal para los eventos propagados está en el tiempo. El evento golpeará el documentobjeto antes que el windowobjeto ya que ocurre primero en la jerarquía, pero esa diferencia generalmente es irrelevante para que pueda elegir cualquiera de los dos. En general, me parece mejor elegir el objeto más cercano a la fuente del evento que satisfaga sus necesidades al manejar eventos propagados. Eso hace pensar que usted escoja documentmás windowcuando cualquiera va a funcionar. Pero, a menudo me acerco aún más a la fuente y uso document.bodyo incluso a un padre común más cercano en el documento (si es posible).

jfriend00
fuente
Tenía curiosidad sobre la cuestión de "burbujear al documento pero no a la ventana". Así que lo probé aquí -> jsfiddle.net/k3qv9/1 ¿Me estoy perdiendo algo o realmente ocurre el burbujeo?
banzomaikaka
1
@JOPLOmacedo: antes de tu comentario, eliminé la parte sobre el burbujeo porque no estoy seguro de qué eventos aparecen en la ventana y cuáles no. El protocolo que siempre he visto es interceptar eventos burbujeantes en todo el documento en el document.bodyobjeto o en el documentobjeto, por lo que no hay ninguna razón para usar windowen eventos burbujeados. En cualquier caso, el punto de mi respuesta es que algunos eventos solo están encendidos windowy algunos eventos solo están encendidos documenty algunos están en ambos, por lo que el OP debe elegir el objeto que corresponde al evento que desean manejar.
jfriend00
Okey Dokey. Eso es lo que suelo hacer también, exactamente por qué decidí probarlo. ¡Gracias por la respuesta!
banzomaikaka
Dado que el evento 'clic' está disponible tanto en el documento como en la ventana, y si registramos el evento tanto en el documento como en la ventana, el controlador de clic del documento se activa primero y luego la ventana. entonces, para este punto de vista, la elección del documento es mejor. jsfiddle.net/3LcVw
codificador
1
Otro ejemplo: si va a agregar a addEventListener("keydown", event)través windowde Samsung TV, entonces no funcionará. Pero harás lo mismo con document, entonces lo hará. Depende también de un dispositivo específico cómo se llaman eventos burbujeados.
Jakub Kubista
4

Encontrará que en JavaScript, generalmente hay muchas formas diferentes de hacer lo mismo o encontrar la misma información. En su ejemplo, está buscando algún elemento que garantice que siempre exista. windowy documentambos encajan perfectamente (con solo algunas diferencias).

Desde la red de desarrollo de mozilla :

addEventListener () registra un único detector de eventos en un único objetivo. El destino del evento puede ser un único elemento en un documento, el documento en sí, una ventana o una solicitud XMLHttpRequest.

Por lo tanto, siempre que pueda contar con que su "objetivo" siempre esté allí, la única diferencia es qué eventos está escuchando, así que use su favorito.

Bryan Wolfford
fuente
55
Esto no es genéricamente cierto. Se producen diferentes eventos en diferentes objetos. documenty windowno recibes los mismos eventos. Debe elegir el objeto que obtiene el evento que le interesa. Algunos eventos pueden ir a ambos documenty window, pero no a todos.
jfriend00
1

El windowenlace se refiere a un objeto incorporado proporcionado por el navegador. Representa la ventana del navegador que contiene el document. Llamar a su addEventListenermétodo registra el segundo argumento (función de devolución de llamada) que se llamará siempre que ocurra el evento descrito por su primer argumento.

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

Deben tenerse en cuenta los siguientes puntos antes de seleccionar una ventana o documento para agregarEventListners

  1. La mayoría de los eventos son para la misma windowo document, pero algunos eventos como resize, y otros eventos relacionados con loading, unloadingyopening/closing todo se debe establecer en la ventana.
  2. Dado que la ventana tiene el documento, es una buena práctica usar el documento para manejar (si puede manejar) ya que el evento golpeará primero al documento.
  3. Internet Explorer no responde a muchos eventos registrados en la ventana, por lo que deberá usar el documento para registrar el evento.
Un consumidor
fuente