Comment puis-je passer des arguments aux gestionnaires d'événements dans jQuery?

Réponses:

110

Le moyen le plus simple est de le faire comme ceci (en supposant que vous ne voulez pas que les informations d'événement soient transmises à la fonction) ...

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

jsFiddle .

Cela crée une fonction anonyme, qui est appelée lorsque l' clickévénement est déclenché. Cela appellera à son tour myfunction()les arguments que vous fournissez.

Si vous souhaitez conserver ThisBinding(la valeur du thismoment où la fonction est appelée, définie sur l'élément qui a déclenché l'événement), appelez la fonction avec call().

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

jsFiddle .

Vous ne pouvez pas passer la référence directement comme l'indique votre exemple, ou son seul argument sera l' objet jQueryevent .

Si vous ne voulez passer la référence, vous devez tirer parti de jQuery proxy()fonction ( ce qui est un wrapper croix navigateur pour Function.prototype.bind()). Cela vous permet de passer des arguments, qui sont liés avant l' eventargument.

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

jsFiddle .

Dans cet exemple, myfunction()serait exécuté avec son ThisBindingintact ( nulln'est pas un objet, donc la thisvaleur normale de l'élément qui a déclenché l'événement est utilisée), avec les arguments (dans l'ordre) arg1, arg2et enfin l' eventobjet jQuery , que vous pouvez ignorer si ce n'est pas obligatoire (ne le nommez même pas dans les arguments de la fonction).

Vous pouvez également utiliser les eventobjets jQuery datapour transmettre des données, mais cela nécessiterait de les modifier myfunction()pour y accéder via event.data.arg1(qui ne sont pas des arguments de fonction comme votre question le mentionne), ou au moins d'introduire une fonction de proxy manuelle comme le premier exemple ou celui généré en utilisant ce dernier exemple.

Alex
la source
2
gardez à l'esprit que vous perdrez le contexte jquery $ (this) dans myfunction (). Pour maintenir, appelez myfunction(this, arg1, arg2)depuis le gestionnaire anonyme. Alors votre fonction peut fairemyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator
11
@geosteve: Si vous vouliez le conserver, utilisez myfunction.call(this, arg1, arg2).
alex
1
Cela ne passe pas d'arguments à la fonction, comme le demande la question. Il appelle une fonction qui appelle une autre fonction. L'imbrication de fonctions dans des fonctions anonymes n'est pas une bonne idée car vous ne pouvez pas dissocier facilement la fonction anonyme.
George Filippakos
1
@ geo1701 Vous pouvez le faire si vous utilisez un espace de noms personnalisé et ne vous y liez qu'une seule fois. Dans la plupart des cas, c'est OK. Mais vous perdez cet avantage que vous avez mentionné.
alex
1
D'accord avec @ geo1701, j'ai dû supprimer le gestionnaire d'événements et sa solution est la seule qui a fonctionné.
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'
});

Vous permet également de lier et de dissocier des gestionnaires d'événements spécifiques à l'aide des méthodes on et off.

Exemple:

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

Cela dissocierait le gestionnaire myfunction de #myid

George Filippakos
la source
Cela ne passe pas d'arguments à la fonction, comme le demande la question.
alex
4
C'est ainsi que vous passez des arguments (vous les enveloppez dans un objet).
George Filippakos
C'est la façon dont vous transmettez des données, mais c'est un peu extensible de les appeler des arguments de fonction.
alex
6
C'est une meilleure solution à la réponse acceptée car elle utilise le modèle recommandé de liaison et de dissociation des écouteurs à l'aide des méthodes On / Off.
George Filippakos
7
Si vous pensez que la dissociation est assez rare, vous devez avoir une expérience très limitée. S'il vous plaît, ne faites pas caca les contributions des autres - il s'agit d'une base de connaissances collective et non d'un concours. Il n'y a pas de bonnes ou de mauvaises réponses.
George Filippakos
12

alors que vous devriez certainement utiliser la réponse d'Alex, la méthode "bind" de la bibliothèque prototype a été normalisée dans Ecmascript 5, et sera bientôt implémentée en natif dans les navigateurs. Cela fonctionne comme ceci:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));
Breton
la source
2
Sera thisdéfini sur un contexte différent si vous utilisez cette méthode, par exemple, si bind()elle est thisdans ce contexte (global), ce gestionnaire de clics peut avoir l' windowobjet thisplutôt qu'une référence à l' #myidélément?
alex
2
@alex vous avez tout à fait raison. jQuery liera l'élément #myid à 'this' dans ses gestionnaires d'événements, et l'utilisation de la méthode bind le remplacera. J'ai écrit ce post il y a plusieurs années, il semble donc difficile de dire ce que je pensais à l'époque. Je suppose que je suppose simplement que les gens qui lisent mes réponses sont assez intelligents pour comprendre ces détails eux-mêmes.
Breton
12
C'est une hypothèse très dangereuse.
Travis
@Travis Au moment d'écrire ces lignes (près de 11 ans après la réponse de Breton), caniuse.com rapporte qu'Ecmascript 5 est supporté par 98,87% des navigateurs. (voir caniuse.com/#search=ECMAScript%205 )
Stephan
@Stephan Mon commentaire ironique était destiné à @Breton pour avoir supposé people reading my answers are smart enough to figure these details out themselves, pas à propos d'Ecmascript.
Travis le
6

Ancien fil, mais à des fins de recherche; essayer:

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

... et consultez le paramètre "data": http://api.jquery.com/on/

par exemple:

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

Il y a déjà d'excellentes réponses, mais de toute façon, voici mes deux cents. Vous pouvez aussi utiliser:

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

Et l'auditeur ressemblerait à:

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

Leo
la source
2

Facile:

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

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