Jak mogę przekazać argumenty do programów obsługi zdarzeń w jQuery?

Odpowiedzi:

111

Najprościej zrobić to w ten sposób (zakładając, że nie chcesz, aby żadne informacje o zdarzeniu przekazywane do funkcji) ...

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

jsFiddle .

Tworzy to anonimową funkcję, która jest wywoływana po clickwyzwoleniu zdarzenia. To z kolei wywoła myfunction()argumenty, które podasz.

Jeśli chcesz zachować ThisBinding(wartość thismomentu wywołania funkcji, ustaw na element, który wyzwolił zdarzenie), wywołaj funkcję za pomocą call().

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

jsFiddle .

Nie możesz przekazać odwołania bezpośrednio w sposób, w jaki stwierdza Twój przykład, albo jego pojedynczy argument będzie obiektem jQueryevent .

Jeśli nie chcesz przekazać odwołanie, należy wykorzystać jQuery w proxy()funkcji (co jest krzyż wrapper dla przeglądarki Function.prototype.bind()). To pozwala przekazać argumenty, które są zobowiązane przed tym eventargumentem.

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

jsFiddle .

W tym przykładzie myfunction()zostałby wykonany w ThisBindingstanie nienaruszonym ( nullnie jest obiektem, więc thisużywana jest normalna wartość elementu, który wywołał zdarzenie), wraz z argumentami (w kolejności) arg1, arg2a na końcu eventobiekt jQuery , który można zignorować jeśli nie jest to wymagane (nawet nie nazywaj tego w argumentach funkcji).

Możesz również użyć eventobiektu jQuery datado przekazywania danych, ale wymagałoby to modyfikacji, myfunction()aby uzyskać do nich dostęp event.data.arg1(które nie są argumentami funkcji, takimi jak wspomniane w pytaniu) lub przynajmniej wprowadzić ręczną funkcję proxy, taką jak poprzedni przykład lub wygenerowany używając tego drugiego przykładu.

Alex
źródło
2
pamiętaj, że stracisz kontekst jquery $ (this) w myfunction (). Aby utrzymać, zadzwoń myfunction(this, arg1, arg2)z anonimowego programu obsługi. Wtedy twoja funkcja może to zrobićmyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator,
11
@geosteve: Jeśli chcesz go zachować, użyj myfunction.call(this, arg1, arg2).
Alex
1
To nie jest przekazywanie argumentów do funkcji, jak zadaje pytanie. To wywołanie funkcji, która wywołuje inną funkcję. Zagnieżdżanie funkcji wewnątrz funkcji anonimowych nie jest dobrym pomysłem, ponieważ nie można łatwo odłączyć funkcji anonimowej.
George Filippakos
1
@ geo1701 Możesz to zrobić, jeśli używasz niestandardowej przestrzeni nazw i powiążesz się z nią tylko raz. W większości przypadków jest OK. Ale tracisz tę korzyść, o której wspomniałeś.
Alex
1
Zgodziłem się z @ geo1701, musiałem usunąć program obsługi zdarzeń, a jego rozwiązanie działało tylko.
Pavel K.
77
$("#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'
});

Umożliwia także wiązanie i odłączanie określonych programów obsługi zdarzeń przy użyciu metod włączania i wyłączania.

Przykład:

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

Spowodowałoby to odłączenie procedury obsługi mojej funkcji od #myid

George Filippakos
źródło
To nie jest przekazywanie argumentów do funkcji, jak zadaje pytanie.
Alex
4
W ten sposób przekazujesz argumenty (zawijasz je wewnątrz obiektu).
George Filippakos
W ten sposób przekazujesz dane, ale wywołanie ich argumentami funkcji jest rozciągnięte.
alex
7
Jest to lepsze rozwiązanie dla zaakceptowanej odpowiedzi, ponieważ wykorzystuje zalecany wzorzec wiązania i odłączania słuchaczy przy użyciu metod włączania / wyłączania.
George Filippakos
7
Jeśli uważasz, że odwiązanie jest dość rzadkie, musisz mieć bardzo ograniczone doświadczenie. Proszę nie kupować wkładów innych osób - jest to zbiorowa baza wiedzy, a nie konkurs. Nie ma dobrych ani złych odpowiedzi.
George Filippakos
12

chociaż z pewnością powinieneś użyć odpowiedzi Alexa, metoda „bind” biblioteki prototypowej została ustandaryzowana w Ecmascript 5 i wkrótce zostanie natywnie zaimplementowana w przeglądarkach. Działa to tak:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));
Breton
źródło
2
Zostanie thisustawiony na inny kontekst, jeśli użyjesz tej metody, na przykład ustawienie bind()jej thisw tym kontekście (globalnym) może spowodować, że ta funkcja obsługi kliknięcia będzie miała windowobiekt, thisa nie odniesienie do #myidelementu?
Alex
2
@alex masz rację. jQuery powiąże element #myid z „this” w swoich programach obsługi zdarzeń, a użycie metody bind spowoduje przesłonięcie tego elementu. Napisałem ten post kilka lat temu, wydaje się, że trudno powiedzieć, o czym wtedy myślałem. Wydaje mi się, że po prostu zakładam, że ludzie czytający moje odpowiedzi są na tyle sprytni, aby samodzielnie rozgryźć te szczegóły.
Breton,
12
To bardzo niebezpieczne założenie.
Travis,
@Travis W chwili pisania tego tekstu (prawie 11 lat po odpowiedzi Bretona), caniuse.com informuje, że Ecmascript 5 jest obsługiwany przez 98,87% przeglądarek. (patrz caniuse.com/#search=ECMAScript%205 )
Stephan
1
@Stephan Mój żartobliwy komentarz skierowany był do @Breton za przypuszczenie people reading my answers are smart enough to figure these details out themselves, a nie o Ecmascript.
Travis
6

Stary wątek, ale do celów wyszukiwania; próbować:

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

... i sprawdź parametr „data”: http://api.jquery.com/on/

na przykład:

function greet( event ) {
  alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {name: "Karl"}, greet );
$( "button" ).on( "click", {name: "Addy"}, greet );
dhc
źródło
4

Są już świetne odpowiedzi, ale tak czy inaczej, oto moje dwa centy. Możesz także użyć:

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

A słuchacz wyglądałby tak:

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

Lew
źródło
2

Prosty:

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

function myHandler(event){
   alert(event.data);     //passed in "event.data"
}
T.Todua
źródło