Bagaimana cara menyampaikan argumen ke penangan peristiwa di jQuery?

92

Dengan kode jQuery seperti:

$("#myid").click(myfunction);

function myfunction(arg1, arg2) {/* something */}

Bagaimana cara menyampaikan argumen myfunctionsaat menggunakan jQuery?

Edward Wong Hau Pepelu Tivrusk
sumber
Kemungkinan duplikat dari Meneruskan fungsi dengan parameter sebagai parameter?
Michał Perłakowski

Jawaban:

111

Cara termudah adalah melakukannya seperti itu (dengan asumsi Anda tidak ingin informasi acara apa pun diteruskan ke fungsi) ...

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

jsFiddle .

Ini membuat fungsi anonim, yang dipanggil saat clickacara dipicu. Ini pada gilirannya akan memanggil myfunction()dengan argumen yang Anda berikan.

Jika Anda ingin mempertahankan ThisBinding(nilai thissaat fungsi dipanggil, setel ke elemen yang memicu kejadian), maka panggil fungsi dengan call().

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

jsFiddle .

Anda tidak dapat meneruskan referensi secara langsung dengan cara yang dinyatakan contoh Anda, atau argumen tunggalnya adalah objek jQueryevent .

Jika Anda tidak ingin lulus referensi, Anda harus memanfaatkan jQuery proxy()fungsi (yang merupakan browser wrapper salib untuk Function.prototype.bind()). Hal ini memungkinkan Anda melewati argumen, yang terikat sebelum itu eventargumen.

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

jsFiddle .

Dalam contoh ini, myfunction()akan dieksekusi dengan ThisBindingutuh ( nullbukan objek, jadi nilai normal thiselemen yang memicu kejadian digunakan), bersama dengan argumen (dalam urutan) arg1, arg2dan akhirnya eventobjek jQuery , yang dapat Anda abaikan. jika tidak diperlukan (bahkan jangan beri nama dalam argumen fungsi).

Anda juga dapat menggunakan eventobjek jQuery datauntuk meneruskan data, tetapi ini akan memerlukan modifikasi myfunction()untuk mengaksesnya melalui event.data.arg1(yang bukan merupakan argumen fungsi seperti pertanyaan Anda menyebutkan), atau setidaknya memperkenalkan fungsi proxy manual seperti contoh sebelumnya atau yang dihasilkan menggunakan contoh terakhir.

alex
sumber
2
perlu diingat, Anda akan kehilangan konteks jquery $ (this) di myfunction (). Untuk mempertahankan, panggil myfunction(this, arg1, arg2)dari penangan anonim. Kemudian fungsi Anda dapat melakukannyamyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator
11
@geosteve: Jika Anda ingin menyimpannya, gunakan myfunction.call(this, arg1, arg2).
alex
1
Itu tidak memberikan argumen ke fungsi, seperti yang ditanyakan oleh pertanyaan. Ini memanggil fungsi yang memanggil fungsi lain. Fungsi bersarang di dalam fungsi anonim bukanlah ide yang baik karena Anda tidak dapat melepaskan fungsi anonim dengan mudah.
George Filippakos
1
@ geo1701 Anda bisa jika Anda menggunakan namespace kustom dan hanya mengikatnya sekali. Untuk sebagian besar tujuan, tidak apa-apa. Tapi Anda kehilangan manfaat yang Anda sebutkan itu.
alex
1
Setuju dengan @ geo1701, saya harus menghapus event handler dan solusinya hanya satu yang berhasil.
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'
});

Juga memungkinkan Anda untuk mengikat dan melepaskan penangan kejadian tertentu menggunakan metode hidup dan mati.

Contoh:

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

Ini akan melepaskan penangan fungsi saya dari #myid

George Filippakos
sumber
Itu tidak memberikan argumen ke fungsi, seperti yang ditanyakan oleh pertanyaan.
alex
4
Begitulah cara Anda menyampaikan argumen (Anda membungkusnya di dalam sebuah objek).
George Filippakos
Begitulah cara Anda menyampaikan data, tetapi memanggil mereka argumen fungsi.
alex
7
Ini adalah solusi yang lebih baik untuk jawaban yang diterima karena menggunakan pola yang disarankan untuk mengikat dan melepaskan pemroses menggunakan metode Nyala / Mati.
George Filippakos
7
Jika menurut Anda pelepasan cukup jarang maka Anda pasti memiliki pengalaman yang sangat terbatas. Harap jangan membuang-buang kontribusi dari orang lain - ini adalah basis pengetahuan kolektif, bukan kompetisi. Tidak ada jawaban benar atau salah.
George Filippakos
12

sementara Anda pasti harus menggunakan jawaban Alex, metode "bind" perpustakaan prototipe telah distandarisasi di Ecmascript 5, dan akan segera diimplementasikan di browser secara native. Ini bekerja seperti ini:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));
Breton
sumber
2
Akan thisdisetel ke konteks yang berbeda jika Anda menggunakan metode ini, misalnya, bind()memasukkannya ke thisdalam konteks itu (global) dapat mengakibatkan handler klik tersebut memiliki windowobjek thissebagai lawan referensi ke #myidelemen?
alex
2
@ alex Anda benar. jQuery akan mengikat elemen #myid ke 'this' di event handlernya, dan menggunakan metode bind akan menimpanya. Saya menulis posting ini beberapa tahun yang lalu sepertinya sangat sulit untuk mengatakan apa yang saya pikirkan saat itu. Saya rasa saya hanya berasumsi bahwa orang-orang yang membaca jawaban saya cukup pintar untuk memahami detail ini sendiri.
Breton
12
Itu asumsi yang sangat berbahaya.
Travis
@Travis Saat tulisan ini dibuat, (hampir 11 tahun setelah jawaban Breton), caniuse.com melaporkan Ecmascript 5 didukung oleh 98,87% browser. (lihat caniuse.com/#search=ECMAScript%205 )
Stephan
1
@Stephan Komentar lidah saya ditujukan kepada @Breton karena berasumsi people reading my answers are smart enough to figure these details out themselves, bukan tentang Ecmascript.
Travis
6

Benang tua, tapi untuk tujuan pencarian; mencoba:

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

... dan periksa parameter "data": http://api.jquery.com/on/

misalnya:

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

Sudah ada jawaban yang bagus, tapi bagaimanapun, ini dua sen saya. Anda juga bisa menggunakan:

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

Dan pendengarnya akan terlihat seperti:

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

Leo
sumber
2

Sederhana:

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

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