Come posso passare argomenti ai gestori di eventi in jQuery?


Risposte:


110

Il modo più semplice è farlo in questo modo (supponendo che tu non voglia che nessuna delle informazioni sull'evento venga passata alla funzione) ...

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

jsFiddle .

Questo crea una funzione anonima, che viene chiamata quando clickviene attivato l' evento. Questo a sua volta chiamerà myfunction()con gli argomenti forniti.

Se vuoi mantenere ThisBinding(il valore di thisquando la funzione viene invocata, impostato sull'elemento che ha attivato l'evento), allora chiama la funzione con call().

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

jsFiddle .

Non puoi passare il riferimento direttamente nel modo in cui afferma il tuo esempio, o il suo unico argomento sarà l' oggetto jQueryevent .

Se non volete passare il riferimento, è necessario sfruttare jQuery proxy()la funzione (che è un wrapper cross browser per Function.prototype.bind()). In questo modo si passa argomenti, che sono legati prima della eventdiscussione.

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

jsFiddle .

In questo esempio, myfunction()potrebbe essere eseguito con la sua ThisBindingintatta ( nullnon è un oggetto, in modo che il normale thisvalore dell'elemento che ha attivato l'evento viene utilizzato), insieme con gli argomenti (in ordine) arg1, arg2ed infine il jQuery eventoggetto, che si può ignorare se non è richiesto (non nominarlo nemmeno negli argomenti della funzione).

Potresti anche usare gli eventoggetti jQuery dataper passare i dati, ma ciò richiederebbe la modifica myfunction()per accedervi tramite event.data.arg1(che non sono argomenti di funzione come menzionati nella tua domanda), o almeno introdurre una funzione proxy manuale come l'esempio precedente o uno generato utilizzando quest'ultimo esempio.


2
tieni presente che perderai il contesto jquery $ (this) in myfunction (). Per mantenere, chiamare myfunction(this, arg1, arg2)dal gestore anonimo. Quindi la tua funzione può faremyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator

11
@geosteve: se vuoi tenerlo, usa myfunction.call(this, arg1, arg2).
alex

1
Questo non è passare argomenti alla funzione, come chiede la domanda. Sta chiamando una funzione che chiama un'altra funzione. Annidare funzioni all'interno di funzioni anonime non è una buona idea in quanto non è possibile svincolare facilmente la funzione anonima.
George Filippakos

1
@ geo1701 Puoi farlo se utilizzi uno spazio dei nomi personalizzato e ti colleghi solo una volta. Per la maggior parte degli scopi, va bene. Ma perdi quel vantaggio che hai menzionato.
alex

1
D'accordo con @ geo1701, ho dovuto rimuovere il gestore eventi e la sua soluzione è solo quella che ha funzionato.
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'
});

Consente inoltre di associare e svincolare gestori di eventi specifici utilizzando i metodi di attivazione e disattivazione.

Esempio:

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

Ciò svincolerebbe il gestore myfunction da #myid


Questo non è passare argomenti alla funzione, come chiede la domanda.
alex

4
È così che passi gli argomenti (li avvolgi all'interno di un oggetto).
George Filippakos

È il modo in cui si passano i dati, ma chiamarli argomenti di funzione è una forzatura.
alex

6
È una soluzione migliore per la risposta accettata in quanto utilizza il modello consigliato di associazione e disassociazione dei listener utilizzando i metodi On / Off.
George Filippakos

7
Se pensi che lo svincolo sia piuttosto raro, devi avere un'esperienza molto limitata. Per favore, non cagare contributi da altri: questa è una base di conoscenza collettiva, non una competizione. Non ci sono risposte giuste o sbagliate.
George Filippakos

12

mentre dovresti certamente usare la risposta di Alex, il metodo "bind" della libreria prototipo è stato standardizzato in Ecmascript 5, e sarà presto implementato nativamente nei browser. Funziona così:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));

2
Sarà thisessere impostato su un contesto diverso, se si utilizza questo metodo, per esempio, bind()ing a thisin quel contesto (globale) può provocare tale gestore click avendo l' windowoggetto come thisal contrario di un riferimento alla #myidelemento?
alex

2
@alex hai perfettamente ragione. jQuery vincolerà l'elemento #myid a 'this' nei suoi gestori di eventi e l'uso del metodo bind sovrascriverà quello. Ho scritto questo post diversi anni fa, sembra quindi è difficile dire cosa stavo pensando in quel momento. Immagino di presumere che le persone che leggono le mie risposte siano abbastanza intelligenti da capire questi dettagli da sole.
Bretone

12
Questo è un presupposto molto pericoloso.
Travis

@Travis Al momento della stesura di questo articolo, (quasi 11 anni dopo la risposta di Breton), caniuse.com segnala che Ecmascript 5 è supportato dal 98,87% dei browser. (vedi caniuse.com/#search=ECMAScript%205 )
Stephan

@Stephan Il mio commento ironico era rivolto a @Breton per aver assunto people reading my answers are smart enough to figure these details out themselves, non su Ecmascript.
Travis

6

Vecchio thread, ma per scopi di ricerca; provare:

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

... e controlla il parametro "data": http://api.jquery.com/on/

per esempio:

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

4

Ci sono già ottime risposte, ma comunque ecco i miei due centesimi. Puoi anche usare:

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

E l'ascoltatore sarebbe simile a:

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


2

Semplice:

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

function myHandler(event){
   alert(event.data);     //passed in "event.data"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.