lunes, 5 de septiembre de 2011

Funciones no-anónimas para eventos en jQuery

Cuando escribimos código con jQuery para gestionar eventos del DOM, normalmente lo hacemos con funciones anónimas que reciben un parámetro e, que es el evento normalizado de jQuery, y además el contexto de ejecución se establece al actual elemento del DOM que provocó el evento.

Forma convencional

$("#Div1").click(function(e) {
   
$(this).text("Hola mundo!");

});

En este ejemplo, la función es anónima, recibe un parámetro e y además this apunta al elemento del DOM Div1.

Esta forma de adjuntar eventos normalmente es la preferida, pero si queremos refactorizar u organizar nuestro código, no es la idónea. Si esta función la quisiéramos adjuntar a varios elementos DOM, podríamos “expandir” el selector de jQuery para que se aplicará la función a más de un elemento, con un código como el siguiente

$("#Div1,#Div2").click(function(e) {
   
$(this).text("Hola mundo!");

});

Esta solución es válida, pero seguimos teniendo el problema de que la función es anónima y eso evita una óptima organización de nuestro código.

Para llegar a la solución final, primero me gustaría probar las distintas opciones que tenemos disponibles (o que al menos se me ocurren) para manejar esta situación.

Evitando la función anónima (I)

$("#Div1").click(Div1Click);


function Div1Click(e) {
   
//The current DOM element within the event bubbling phase.
   
var that = e.currentTarget;
   
$(that).text("Hola mundo!");   

}

En este ejemplo, hemos definido una función con nombre Div1Click, que podemos mover al fichero .js que creamos oportuno, y que utilizamos para gestionar el evento. Para resolver la referencia a this, utilizamos e.currentTarget, esto es así porque si utilizáramos this directamente, en realidad estaríamos referenciando al objeto window.

Evitando la función anónima (II)

$("#Div1").click(function(e) { 
   
Div1Click(e, this); 

});


function Div1Click(e, that) {
   
$(that).text("Hola mundo!");   

}

En este ejemplo, utilizamos una función anónima que nos sirve sólo para llamar a Div1Click con los argumentos e y that.

Evitando la función anónima (III)

$("#Div1").click(function(e) { 
   
Div1Click.call(this); 

});


function Div1Click() {
   
$(this).text("Hola mundo!");   

}

En este otro ejemplo, utilizamos de nuevo una función anónima, pero esta vez no queremos pasarle el argumento that (no nos gusta, ¡no es güay!), así que utilizamos call  para establecer el contexto de this al elemento DOM actual.

Esta solución es buena, pero hemos perdido el argumento e (el evento de jQuery).

Evitando la función anónima (IV) y ¡FINAL FELIZ!

$("#Div1").click(function(e) { 
   
var args = [e];
   
Div1Click.apply(this, args); 

});


function Div1Click(e) {
   
$(this).text("Hola mundo!");   

}

Finalmente, tenemos una función con nombre, que recibe el parámetro e con el evento de jQuery y además tiene correctamente establecido el contexto de ejecución de this.

Un saludo!

1 comentario:

  1. Concuerdo contigo de evitar las funciones anónimas, me parece que por los ejemplos de los manuales se suele abusar de su uso. En todo caso te recomiendo algo para tus manuales, solo un pequeño detalle. A simple vista podría yo decir que vienes de programar en Visual Basic, por las mayúsculas inciales. Una vez alguien me dijo que da igual, y es cierto pero si trabajamos con JavaScript, pues no se estila hacerlo así, fíjate nomás el nombre de jQuery, comienza con minúscula, es por algo.

    ResponderEliminar