Diferença entre document.addEventListener e window.addEventListener?

135

Ao usar o PhoneGap, ele tem algum código JavaScript padrão que usa document.addEventListener, mas eu tenho meu próprio código que usa window.addEventListener:

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

Qual é a diferença e qual é melhor usar?

Charlie
fonte

Respostas:

160

Os objetos documente windowsão diferentes e eles têm alguns eventos diferentes. O uso addEventListener()deles ouve eventos destinados a um objeto diferente. Você deve usar aquele que realmente tem o evento em que está interessado.

Por exemplo, há um "resize"evento no windowobjeto que não está no documentobjeto.

Por exemplo, o "DOMContentLoaded"evento está apenas no documentobjeto.

Então, basicamente, você precisa saber em qual objeto recebe o evento em que está interessado e usar .addEventListener()nesse objeto específico.

Aqui está um gráfico interessante que mostra quais tipos de objetos criam quais tipos de eventos: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_reference


Se você estiver ouvindo um evento propagado (como o evento click), poderá ouvir esse evento no objeto de documento ou no objeto de janela. A única diferença principal para eventos propagados está no tempo. O evento atingirá o documentobjeto antes do windowobjeto, uma vez que ocorre primeiro na hierarquia, mas essa diferença geralmente é irrelevante para que você possa escolher qualquer um. Acho que geralmente é melhor escolher o objeto mais próximo da origem do evento que atenda às suas necessidades ao lidar com eventos propagados. Isso sugeriria que você escolher documentsobre windowquando ou vai funcionar. Porém, eu costumava me aproximar ainda mais da fonte e usar document.bodyou até mesmo um parente mais próximo no documento (se possível).

jfriend00
fonte
Fiquei curioso sobre o assunto "borbulhando no documento, mas não na janela". Então eu testei aqui -> jsfiddle.net/k3qv9/1 Estou faltando alguma coisa ou a bolha realmente ocorre?
banzomaikaka
1
@JOPLOmacedo - antes do seu comentário, eu removi a parte sobre bolhas, pois não sabia quais eventos borbulham na janela e quais não. O protocolo que eu sempre vi é o de interceptar documentos grandes eventos de bolhas no document.bodyobjeto ou no documentobjeto, para que não haja motivo para usá window-los. De qualquer forma, o ponto da minha resposta é que alguns eventos estão apenas ativados windowe alguns estão ativos documente outros estão em ambos, portanto, o OP deve escolher o objeto que corresponde ao evento que deseja manipular.
usar o seguinte comando
Entendido. É o que eu costumo fazer também - exatamente por que decidi testá-lo. Obrigado pela resposta!
banzomaikaka
Como o evento 'click' está disponível no documento e na janela e, se registrarmos o evento no documento e na janela, o manipulador de clique do documento será acionado primeiro e depois na janela. portanto, para esse ponto de vista, a escolha do documento é melhor. jsfiddle.net/3LcVw
codificador
1
Outro exemplo: se você adicionar uma addEventListener("keydown", event)via windowpara a Samsung TV, ela não funcionará. Mas você fará a mesma coisa document, e então fará. Depende também do dispositivo específico como ele chama eventos com bolhas.
Jakub Kubista 20/01
4

Você encontrará que, em javascript, geralmente existem muitas maneiras diferentes de fazer a mesma coisa ou encontrar as mesmas informações. No seu exemplo, você está procurando por algum elemento que é garantido que sempre existe. windowe documentambos se encaixam na conta (com apenas algumas diferenças).

Da rede mozilla dev :

addEventListener () registra um único ouvinte de evento em um único destino. O destino do evento pode ser um único elemento em um documento, o próprio documento, uma janela ou um XMLHttpRequest.

Contanto que você possa contar com o seu "alvo" sempre presente, a única diferença é que eventos você está ouvindo; portanto, use o seu favorito.

Bryan Wolfford
fonte
5
Isso não é genericamente verdade. Eventos diferentes ocorrem em objetos diferentes. documente windownão recebe os mesmos eventos. Você deve escolher o objeto que obtém o evento no qual está interessado. Alguns eventos podem ir para ambos documente window, mas não para todos.
usar o seguinte comando
1

A windowligação refere-se a um objeto interno fornecido pelo navegador. Representa a janela do navegador que contém o document. A chamada de seu addEventListenermétodo registra o segundo argumento (função de retorno de chamada) a ser chamado sempre que ocorrer o evento descrito por seu primeiro argumento.

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

Os seguintes pontos devem ser observados antes da janela ou documento selecionado para addEventListners

  1. A maioria dos eventos são os mesmos para windowou documentmas alguns eventos como resize, e outros eventos relacionados com a loading, unloadinge opening/closingtodos devem ser definidos na janela.
  2. Como o window possui o documento, é uma boa prática usar o documento para manipular (se ele puder manipular), pois o evento atingirá o documento primeiro.
  3. O Internet Explorer não responde a muitos eventos registrados na janela; portanto, você precisará usar o documento para registrar o evento.
AConsumidor
fonte