¿Cómo puedo pasar argumentos a los controladores de eventos en jQuery?

Respuestas:

110

La forma más sencilla es hacerlo así (asumiendo que no desea que la información del evento se pase a la función) ...

$("#myid").click(function() {
    myfunction(arg1, arg2);
});

jsFiddle .

Esto crea una función anónima, que se llama cuando clickse activa el evento. Esto a su vez llamará myfunction()con los argumentos que proporciones.

Si desea mantener el ThisBinding(el valor de thiscuando se invoca la función, establecido en el elemento que desencadenó el evento), llame a la función con call().

$("#myid").click(function() {
    myfunction.call(this, arg1, arg2);
});

jsFiddle .

No puede pasar la referencia directamente en la forma en que indica su ejemplo, o su único argumento será el objeto jQueryevent .

Si usted no quiere pasar la referencia, debe aprovechar de jQuery proxy()función (que es un envoltorio de navegadores para Function.prototype.bind()). Esto le permite pasar argumentos, que están vinculados antes del eventargumento.

$("#myid").click($.proxy(myfunction, null, arg1, arg2));   

jsFiddle .

En este ejemplo, myfunction()se ejecutaría con su ThisBindingintacto ( nullno es un objeto, por lo thisque se usa el valor normal del elemento que desencadenó el evento), junto con los argumentos (en orden) arg1, arg2y finalmente el eventobjeto jQuery , que puede ignorar si no es necesario (ni siquiera lo nombre en los argumentos de la función).

También puede usar el eventobjeto jQuery datapara pasar datos, pero esto requeriría modificarlo myfunction()para acceder a él a través de event.data.arg1(que no son argumentos de función como menciona su pregunta), o al menos introducir una función de proxy manual como el ejemplo anterior o uno generado utilizando el último ejemplo.

alex
fuente
2
tenga en cuenta que perderá el contexto jquery $ (this) en myfunction (). Para mantener, llame myfunction(this, arg1, arg2)desde el controlador anónimo. Entonces su función puede hacerlomyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator
11
@geosteve: Si desea conservarlo, use myfunction.call(this, arg1, arg2).
alex
1
Eso no es pasar argumentos a la función, como pide la pregunta. Está llamando a una función que llama a otra función. Anidar funciones dentro de funciones anónimas no es una buena idea, ya que no es posible desvincular la función anónima fácilmente.
George Filippakos
1
@ geo1701 Puede hacerlo si usa un espacio de nombres personalizado y solo se vincula una vez a él. Para la mayoría de los propósitos, está bien. Pero pierde ese beneficio que mencionó.
alex
1
De acuerdo con @ geo1701, tuve que eliminar el controlador de eventos y su solución es la única que funcionó.
Pavel K
76
$("#myid").on('click', {arg1: 'hello', arg2: 'bye'}, myfunction);

function myfunction(e) {

    var arg1 = e.data.arg1;
    var arg2 = e.data.arg2;

    alert(arg1);
    alert(arg2);

}

//call method directly:
myfunction({
    arg1: 'hello agian', 
    arg2: 'bye again'
});

También le permite vincular y desvincular controladores de eventos específicos utilizando los métodos on y off.

Ejemplo:

$("#myid").off('click', myfunction);

Esto desvincularía el controlador myfunction de #myid

George Filippakos
fuente
Eso no es pasar argumentos a la función, como pide la pregunta.
alex
4
Así es como pasa los argumentos (los envuelve dentro de un objeto).
George Filippakos
Así es como se pasan los datos, pero es un tramo llamarlos argumentos de función.
alex
6
Es una mejor solución para la respuesta aceptada, ya que utiliza el patrón recomendado de vinculación y desvinculación de oyentes mediante los métodos On / Off.
George Filippakos
7
Si cree que la desvinculación es bastante rara, debe tener una experiencia muy limitada. Por favor, no haga caca en las contribuciones de otros: esta es una base de conocimiento colectiva, no una competencia. No hay respuestas correctas o incorrectas.
George Filippakos
12

Aunque ciertamente debería usar la respuesta de Alex, el método "bind" de la biblioteca prototipo se ha estandarizado en Ecmascript 5 y pronto se implementará en los navegadores de forma nativa. Funciona así:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));
Bretón
fuente
2
¿ thisSe establecerá en un contexto diferente si usa este método, por ejemplo, si bind()lo hace thisen ese contexto (global) puede resultar en que el controlador de clic tenga el windowobjeto thisen lugar de una referencia al #myidelemento?
alex
2
@alex tienes toda la razón. jQuery vinculará el elemento #myid a 'this' en sus controladores de eventos, y el uso del método bind anulará eso. Escribí esta publicación hace varios años, parece que es difícil decir lo que estaba pensando en ese momento. Supongo que simplemente asumo que las personas que leen mis respuestas son lo suficientemente inteligentes como para descubrir estos detalles por sí mismas.
Breton
12
Esa es una suposición muy peligrosa.
Travis
@Travis Al momento de escribir este artículo, (casi 11 años después de la respuesta de Breton), caniuse.com informa que Ecmascript 5 es compatible con el 98,87% de los navegadores. (ver caniuse.com/#search=ECMAScript%205 )
Stephan
@Stephan Mi comentario irónico estaba dirigido a @Breton por asumir people reading my answers are smart enough to figure these details out themselves, no sobre Ecmascript.
Travis
6

Hilo antiguo, pero con fines de búsqueda; tratar:

$(selector).on('mouseover',...);

... y consulte el parámetro "datos": http://api.jquery.com/on/

p.ej:

function greet( event ) {
  alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {name: "Karl"}, greet );
$( "button" ).on( "click", {name: "Addy"}, greet );
dhc
fuente
4

Ya hay grandes respuestas, pero de todos modos, aquí están mis dos centavos. También puedes usar:

$("#myid").click({arg1: "foo", arg2: "bar"}, myfunction)

Y el oyente se vería así:

function myfunction(event){ alert(event.data.arg1); alert(event.data.arg2); }

León
fuente
2

Sencillo:

$(element).on("click", ["Jesikka"],  myHandler);

function myHandler(event){
   alert(event.data);     //passed in "event.data"
}
T.Todua
fuente