Una vez que se desencadena un evento es posible utilizarlo como objeto en JavaScript. Además que, dependiendo el que modelo se esté utilizando, el evento sigue un flujo a través del DOM.
Evento
Una vez que asociamos un evento a una acción podemos incluir como parámetro el evento que se ejecutó. Al hacer esto, el evento está disponible como objeto – con atributos y métodos -.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo</title>
</head>
<body>
<div id='contenedor'>
<h1>Soy un título</h1>
<p id='parrafo' >
Ejemplo
</p>
</div>
</body>
<script>
var parrafo = document.getElementById("parrafo")
parrafo.addEventListener("click", parrafo_click)
function parrafo_click(e) {
console.log(e)
}
</script>
</html>
Esto nos permite tener más control sobre la funcionalidad que queremos desarrollar, además de que posible modificar el comportamiento predeterminado que el evento tiene en el navegador.
Algunos atributos del evento son:
Atributo | Descripción |
target | Elemento que tiene el evento asociado. |
currentTarget | Elemento en donde se está aplicando el evento. |
altKey | Indica si está presionada la tecla ALT cuando se da un clic |
ctrlKey | Indica si está presionada la tecla CTRL cuando se da un clic |
shiftKey | Indica si está presionada la tecla SHIFT cuando se da un clic |
type | Tipo de evento que se realizó. |
pageX / pageY | Tiene las coordenadas del cursor donde se dio un click |
Es posible que algunos atributos y métodos cambien dependiendo del tipo de evento.
Captura y Propagación
La captura y propagación son modelos que determinan qué evento se desencadena primero cuando un nodo hijo y un nodo padre tienen asociado el mismo evento.
Captura
Este modelo analiza el documento desde el nodo raíz hacia el nodo sobre el cuál se desarrollo el evento.
En este caso se desencadena primero el evento en el nodo padre y después en el nodo hijo.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Captura</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
titulo.addEventListener('click', rastrear_evento ,true);
contenido.addEventListener('click', rastrear_evento, true);
contenedor.addEventListener('click', rastrear_evento, true);
body.addEventListener('click', rastrear_evento, true);
html.addEventListener('click', rastrear_evento, true);
function rastrear_evento(e) {
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
}
</script>
</html>
Propagación
Este modelo analiza el documento desde el nodo nodo sobre el cuál se desarrollo el evento hacia el nodo padre.
En este caso se desencadena primero el evento en el nodo padre y después en el nodo hijo.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Propagación</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
titulo.addEventListener('click', rastrear_evento ,false);
contenido.addEventListener('click', rastrear_evento, false);
contenedor.addEventListener('click', rastrear_evento, false);
body.addEventListener('click', rastrear_evento, false);
html.addEventListener('click', rastrear_evento, false);
function rastrear_evento(e) {
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
}
</script>
</html>
Cancelar
Se puede cancelar el flujo de la captura y la propagación utilizando cancelBubble (IE) y stopPropagation (IE9+ / otros).
De esta manera, si otros nodos tienen asociado el mismo evento lo pueden utilizar sin que se mezclen eventos.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Captura</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
titulo.addEventListener('click', rastrear_evento ,true);
contenido.addEventListener('click', rastrear_evento, true);
contenedor.addEventListener('click', rastrear_evento, true);
body.addEventListener('click', rastrear_evento, true);
html.addEventListener('click', rastrear_evento, true);
function rastrear_evento(e) {
if (!e) {
var e = window.event;
}
// La propiedad cancelBubble solo es soportada por IE
// Evita la propagación.
// No afecta al funcionamiento en otros navegadores
e.cancelBubble = true;
if (e.stopPropagation) {
e.stopPropagation();
}
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Propagación</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
titulo.addEventListener('click', rastrear_evento ,false);
contenido.addEventListener('click', rastrear_evento, false);
contenedor.addEventListener('click', rastrear_evento, false);
body.addEventListener('click', rastrear_evento, false);
html.addEventListener('click', rastrear_evento, false);
function rastrear_evento(e) {
if (!e) {
var e = window.event;
}
// La propiedad cancelBubble solo es soportada por IE
// Evita la propagación.
// No afecta al funcionamiento en otros navegadores
e.cancelBubble = true;
if (e.stopPropagation) {
e.stopPropagation();
}
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
}
</script>
</html>
Nota
La w3 – ( especificación / borrador )- implementa ambos modelos.
Oldie (IE6, IE7, IE8) utiliza únicamente el modo de propagación pero IE9+ ya soporta ambos modelos.
Remover Eventos
Para quitar un evento asociado a un nodo con addEventListener se utiliza removeEventListener, si se utilizó attachEvent se utiliza detachEvent.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Captura</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
;(function asociar_eventos() {
if (titulo.addEventListener) {
titulo.addEventListener('click', rastrear_evento ,true);
contenido.addEventListener('click', rastrear_evento, true);
contenedor.addEventListener('click', rastrear_evento, true);
body.addEventListener('click', rastrear_evento, true);
html.addEventListener('click', rastrear_evento, true);
} else {
titulo.attachEvent('onclick', rastrear_evento);
contenido.attachEvent('onclick', rastrear_evento);
contenedor.attachEvent('onclick', rastrear_evento);
body.attachEvent('onclick', rastrear_evento);
html.attachEvent('onclick', rastrear_evento);
}
}());
function rastrear_evento(e) {
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
remover_eventos();
}
function remover_eventos() {
if (titulo.removeEventListener) {
titulo.removeEventListener('click', rastrear_evento ,true);
contenido.removeEventListener('click', rastrear_evento, true);
contenedor.removeEventListener('click', rastrear_evento, true);
body.removeEventListener('click', rastrear_evento, true);
html.removeEventListener('click', rastrear_evento, true);
} else {
titulo.detachEvent('click', rastrear_evento);
contenido.detachEvent('click', rastrear_evento);
contenedor.detachEvent('click', rastrear_evento);
body.detachEvent('click', rastrear_evento);
html.detachEvent('click', rastrear_evento);
}
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Ejemplo - Propagación</title>
<style>
#contenedor {width: 940px; height: 500px; border: 1px solid #333; margin: 0 auto;}
#contenido { width: 500px; height: 200px; margin: 150px auto; background: #555; text-align: center; line-height: 200px;}
</style>
</head>
<body>
<div id='contenedor'>
<div id='contenido'>
<h1>Clic Aquí</h1>
</div>
</div>
</body>
<script>
var titulo = document.getElementsByTagName('h1')[0];
var contenido = document.getElementById('contenido');
var contenedor = document.getElementById('contenedor');
var body = document.getElementsByTagName('body')[0];
var html = document.getElementsByTagName('html')[0];
;(function asociar_eventos() {
if (titulo.addEventListener) {
titulo.addEventListener('click', rastrear_evento ,false);
contenido.addEventListener('click', rastrear_evento, false);
contenedor.addEventListener('click', rastrear_evento, false);
body.addEventListener('click', rastrear_evento, false);
html.addEventListener('click', rastrear_evento, false);
} else {
titulo.attachEvent('onclick', rastrear_evento);
contenido.attachEvent('onclick', rastrear_evento);
contenedor.attachEvent('onclick', rastrear_evento);
body.attachEvent('onclick', rastrear_evento);
html.attachEvent('onclick', rastrear_evento);
}
}());
function rastrear_evento(e) {
console.log('El evento: ' + e.type + ' comenzó en: ' + e.target.nodeName + '. Ahora está en: ' + e.currentTarget.nodeName);
remover_eventos();
}
function remover_eventos() {
if (titulo.removeEventListener) {
titulo.removeEventListener('click', rastrear_evento ,false);
contenido.removeEventListener('click', rastrear_evento, false);
contenedor.removeEventListener('click', rastrear_evento, false);
body.removeEventListener('click', rastrear_evento, false);
html.removeEventListener('click', rastrear_evento, false);
} else {
titulo.detachEvent('click', rastrear_evento);
contenido.detachEvent('click', rastrear_evento);
contenedor.detachEvent('click', rastrear_evento);
body.detachEvent('click', rastrear_evento);
html.detachEvent('click', rastrear_evento);
}
}
</script>
</html>
Por último
Después de estas publicaciones ya tienes el conocimiento básico de qué es el DOM y cómo utilizarlo en JavaScript.