I was thinking about this situation that was added between the parameters of .on
the possibility to pass arbitrary data to the function of handler . Any object passed as a parameter just before the handler will be available within it via event.data
. Example:
function retornaNada(evento) {
var data = evento.data;
console.log(data.foo); // Imprime "bar"
}
$("a").on("click", { foo:"bar" }, retornaNada);
Several other jQuery methods accept this data
parameter. In the case of "on", the general form (according to the documentation) is:
.on (events [ selector] [ data], handler (eventObject))
If this is not enough for you (eg you already have a function ready, and you want to use it without modification as the handler of the event), then you need to transform it by operation currying . There are several ways to do this:
currying "manual":
$("a").on("click", function(e) { retornaNada(10); });
jQuery.proxy
:
$("a").on("click", jQuery.proxy(retornaNada, meuThis, 10));
Function that returns function:
function tranforma(parametro) {
return function(evento) {
retornaNada(parametro);
}
}
$("a").on("click", transforma(10));
or more generic:
function tranforma(fn, meuThis, parametro) {
return function(evento) {
fn.call(meuThis, parametro);
}
}
$("a").on("click", transforma(retornaNada, meuThis, 10));
or even more generic (arriving at a point that is almost identical to jQuery.proxy
):
function tranforma(fn, meuThis) {
var args = Array.prototype.slice.call(arguments, 2, arguments.length);
return function(evento) {
fn.apply(meuThis, args);
}
}
$("a").on("click", transforma(retornaNada, meuThis, 10));
Update: on the use of this
In both jQuery.proxy
and my transforma
(in more generic forms), a meuThis
parameter is expected. This is because every JavaScript function invocation expects a binding for the this
keyword, even when the function is not being called in the context of an object (ie it is not a method ). Example:
console.log(this); // Vai imprimir o "objeto global" (no caso de um browser, "window")
function a() {
console.log(this);
}
a(); // também imprime o objeto global
var obj = { x:a };
obj.x(); // Vai imprimir "obj"
obj.criaLinks = function() {
$("a").on("click", jQuery.proxy(retornaNada, this, 10));
// Como se fosse: obj.retornaNada(10)
$("a").on("click", jQuery.proxy(retornaNada, window, 10));
// Como se fosse: window.retornaNada(10)
$("a").on("click", jQuery.proxy(retornaNada, { foo:"bar" }, 10));
// Como se fosse: { foo:"bar" }.retornaNada(10)
};
obj.criaLinks();