Simular la función live de jQuery con JavaScript

Es muy probable que os hayáis preguntado alguna vez como funciona jQuery.live(). Veámos un pequeño truco para simularlo con JavaScript plano.

Algunos de vosotros posiblemente hayáis oido hablar de la función live. Para los que no (me resulta extraño, ya que yo la uso constantemente) aquí una breve explicación de lo que hace.

Normalmente, cuando asignamos una acción a un evento de un elemento HTML, lo hacemos definiendo el atributo relativo al evento (puedes encontrar una lista con los atributos aquí). Por ejemplo, si quiero que una función se ejecute al pinchar sobre un elemento, asignaré al atributo onclick una función JavaScript. Esta asignación puede hacerse mediante HTML o JavaScript.

<a id="anchor" href="#" onclick="alert('¡Click!'); return false;">Anchor</a>

<script>
document.getElementById('anchor').onclick = function() {
	alert('¡Click!');
	return false;
}
</script>

En el ejemplo hecho con HTML asignamos el atributo a un elemento concreto, mientras que con JavaScript podemos asignarlo a unos cuantos elementos a la vez (aunque en este caso también lo asignamos a un elemento). Hay que tener una cosa clara, y es que el código solo se ejecuta una vez, es decir, el atributo onclick solo se asignará a los elementos que estén presentes en el momento en el que se ejecuta el código. En el caso de que creemos otro elemento más tarde, el evento ya no funcionará en él. Se ve más fácil con un ejemplo:

<div id="wrapper">
	<a href="#">Anchor 1</a>
</div>

<script>
// Cargamos todos los <a> y les definimos el evento.
var allAnchor = document.getElementsByTagName('a');
for (var i = allAnchor.length - 1; i >= 0; i--) {
	allAnchor[i].onclick = function() {
		alert('¡Click!');
		return false;
	}
}

// Creamos un nuevo elemento.
var newAnchor = document.createElement('a');
newAnchor.setAttribute('href', '#');
newAnchor.innerHTML = 'Anchor 2';
document.getElementById('wrapper').appendChild(newAnchor);
</script>

Si ejecutáis el código de arriba veréis que al hacer click sobre el primer elemento salta una alerta, pero al hacer click sobre el segundo (creado después de que los eventos se asignasen) no salta ningún evento especial y nos lleva a la dirección indicada.

La creación dinámica de elementos es algo que está a la orden del día, por eso hay un pequeño truco que nos permite asignar eventos incluso a elementos creados posteriormente.

La clave es darle un enfoque diferente al asunto. Esta vez asignaremos el evento al documento, y cuando este salte (cuando hagamos click el cualquier lugar de la página) comprobaremos sobre donde se ha pinchado. En el caso de que este sea algún elemento que nos interese, ejecutaremos la función deseada.

Veámos el ejemplo de arriba con el nuevo enfoque, esta vez funcionarán los dos enlaces.

<div id="wrapper">
	<a href="#">Anchor 1</a>
</div>

<script>
// Asignamos el evento deseado al documento.
document.onclick = function(event) {
	// Guardamos el elemento sobre el que se ha pinchado.
	var el = event.target;

	// Comprobamos que sea un <a>
	if (el.nodeName == 'A') {
		alert('¡Click!');
		return false;
	}
}

// Creamos un nuevo elemento.
var newAnchor = document.createElement('a');
newAnchor.setAttribute('href', '#');
newAnchor.innerHTML = 'Anchor 2';
document.getElementById('wrapper').appendChild(newAnchor);
</script>

Dentro de event.target también hay otras variables como por ejemplo id, classname, etcétera. Con ellos podremos localizar cualquier elemento al igual que si utilizasemos document.getElement(s)By(Id/TagName…).

Y esto es todo. Muchos de vosotros puedes que utilizaseis frameworks pesados como jQuery solo por esta función. Ahora sabéis que no es necesario, y para escribir varias líneas de código JavaScript puro puede ser suficiente a pesar de resultar más repetitivo. Esto aligerará la web en muchos casos y puede resultar en un gran decremento del bandwidth.

Espero que haya sido de ayuda. Cualquier duda no tenéis más que preguntar. Saludos.

comments powered by Disqus