Níveis de Eventos no Modelo de Objetos do Documento (DOM)
O DOM (Modelo de Objetos do Documento) especifica diferantes níveis para manipulação de eventos, incluindo DOM0, DOM2 e DOM3. Cada nível oferece métodos distintos para vincular e desvincular ouvintes de eventos.
Eventos no Nível 0 do DOM
Neste nível, os eventos são atribuídos diretamente a propriedades de elementos. Para vincular um evento, utiliza-se a propriedade onclick, e para desvincular, atribui-se null a essa propriedade.
elemento.onclick = function() {};
elemento.onclick = null;
Eventos no Nível 2 do DOM
O DOM nível 2 introduz os métodos addEventListener e removeEventListener para gerenciar eventos. O método addEventListener aceita três parâmetros: o nome do evento, a função manipuladora e um booleano opcional que indica se o evento deve ser tratado na fase de captura (true) ou bolha (false, padrão).
Para compatibilidade com navegadores antigos, como o Internet Explorer 8 e versões inferiores, utilizava-se attachEvent e detachEvent, que só suportam a fase de bolha.
elemento.addEventListener('click', function() {}, false);
elemento.removeEventListener('click', function() {}, false);
// Para navegadores legados
elemento.attachEvent('onclick', function() {});
elemento.detachEvent('onclick', function() {});
Eventos no Nível 3 do DOM
O DOM nível 3 expande os tipos de eventos disponíveis, adicionando categorias como eventos de teclado, mouse e rolagem, além de suporte para namespaces.
Modelo de Propagação de Eventos
O modelo de eventos do DOM envolve duas fases principais: captura (propagação descendente desde o window até o elemento alvo) e bolha (propagação ascendente do elemento alvo até o window). O fluxo completo é: fase de captura, fase alvo e fase de bolha.
Fluxo de Captura de Eventos
Durante a fase de captura, o evento é propagado do objeto window, passando por document, html, body, até atingir o elemento alvo. O código a seguir demonstra esse fluxo, vinculando ouvintes de captura a diferentes elementos.
<div id="alvo">Elemento Alvo</div>
<script>
const alvo = document.getElementById('alvo');
alvo.addEventListener('click', () => {
console.log('alvo');
}, true);
window.addEventListener('click', () => {
console.log('janela');
}, true);
document.addEventListener('click', () => {
console.log('documento');
}, true);
document.documentElement.addEventListener('click', () => {
console.log('html');
}, true);
document.body.addEventListener('click', () => {
console.log('corpo');
}, true);
</script>
O console exibirá a ordem: janela, documento, html, corpo, alvo. Se os eventos fossem registrados para a fase de bolha, a ordem seria invertida.
Métodos Comuns do Objeto Evento
O objeto evento fornece métodos essenciais para controle de comportamento:
- preventDefault(): Impede a ação padrão do navegador.
- stopPropagation(): Interrompe a propagação do evento.
- currentTarget: Referencia o elemento ao qual o evanto está vinculado.
- target: Indica o elemento que originou o evento.
- stopImmediatePropagation(): Bloqueia a execução de outros ouvintes do mesmo tipo no elemento atual.
Criação de Eventos Personalizados
Usando o Construtor Event
O construtor Event permite criar eventos personalizados. No entanto, não suporta parâmetros adicionais. Para acionar o evento, utiliza-se dispatchEvent no elemento.
<div id="destino">Elemento Destino</div>
<script>
const destino = document.getElementById('destino');
const eventoPersonalizado = new Event('alerta');
destino.addEventListener('alerta', (e) => {
console.log(e.detail); // undefined, pois Event não tem detail
});
setTimeout(() => {
destino.dispatchEvent(eventoPersonalizado);
}, 1000);
</script>
Usando o Construtor CustomEvent
Para passar dados ao evento, utilize CustomEvent, que inclui a propriedade detail. Isso permite enviar parâmetros que podem ser acessados no menipulador.
<div id="meta">Elemento Meta</div>
<script>
const meta = document.getElementById('meta');
const eventoComDados = new CustomEvent('alerta', { detail: 'teste' });
meta.addEventListener('alerta', (e) => {
console.log(e.detail); // 'teste'
});
setTimeout(() => {
meta.dispatchEvent(eventoComDados);
}, 1000);
</script>