Saya mencoba untuk memahami perbedaan tertentu antara langsung dan didelegasikan event handler menggunakan jQuery .on () metode . Secara khusus, kalimat terakhir dalam paragraf ini:
Ketika a
selector
disediakan, pengendali acara disebut sebagai didelegasikan . Pawang tidak dipanggil ketika peristiwa terjadi langsung pada elemen terikat, tetapi hanya untuk keturunan (elemen dalam) yang cocok dengan pemilih. jQuery mem-gelembung-kan event dari target event hingga ke elemen di mana handler dilampirkan (yaitu, elemen terdalam ke terluar) dan menjalankan handler untuk elemen apa pun di sepanjang jalur yang cocok dengan pemilih.
Apa yang dimaksud dengan "menjalankan penangan untuk elemen apa pun"? Saya membuat halaman pengujian untuk bereksperimen dengan konsep itu. Tetapi kedua konstruksi berikut mengarah pada perilaku yang sama:
$("div#target span.green").on("click", function() {
alert($(this).attr("class") + " is clicked");
});
atau,
$("div#target").on("click", "span.green", function() {
alert($(this).attr("class") + " is clicked");
});
Mungkin seseorang dapat merujuk pada contoh berbeda untuk memperjelas hal ini? Terima kasih.
Jawaban:
Kasus 1 (langsung):
== Hei! Saya ingin setiap span.green di dalam target div untuk mendengarkan: ketika Anda diklik, lakukan X.
Kasus 2 (didelegasikan):
== Hei, target div #! Ketika salah satu elemen anak Anda yang "span.green" diklik, lakukan X dengan mereka.
Dengan kata lain...
Dalam kasus 1, masing-masing rentang tersebut telah diberikan instruksi secara individual. Jika rentang baru dibuat, mereka tidak akan pernah mendengar instruksi dan tidak akan menanggapi klik. Setiap rentang bertanggung jawab langsung untuk acara sendiri.
Dalam kasus 2, hanya kontainer yang telah diberi instruksi; itu bertanggung jawab untuk memperhatikan klik atas nama elemen anaknya. Pekerjaan menangkap acara telah didelegasikan . Ini juga berarti bahwa instruksi akan dilakukan untuk elemen anak yang dibuat di masa depan.
sumber
on()
memungkinkan dua argumen ketika itu hampir sama dengan menggunakanclick()
?e.target
akan menjadi target awal acara klik (bisa berupa simpul anak jikaspan.green
memiliki anak). Dari dalam handler, Anda harus menggunakanthis
referensi. Lihat biola ini .Cara pertama
$("div#target span.green").on()
,, mengikat handler klik langsung ke rentang yang cocok dengan pemilih pada saat kode dieksekusi. Ini berarti jika rentang lain ditambahkan kemudian (atau kelasnya diubah agar sesuai) mereka telah terjawab dan tidak akan memiliki penangan klik. Ini juga berarti jika Anda kemudian menghapus kelas "hijau" dari salah satu rentang penangan kliknya akan terus berjalan - jQuery tidak melacak bagaimana penangan ditugaskan dan memeriksa untuk melihat apakah pemilih masih cocok.Cara kedua
$("div#target").on()
,, mengikat penangan klik ke div yang cocok (sekali lagi, ini bertentangan dengan yang cocok pada saat itu), tetapi ketika klik terjadi di suatu tempat di div fungsi penangan hanya akan dijalankan jika klik terjadi bukan hanya di div tetapi di elemen anak yang cocok dengan pemilih di parameter kedua ke.on()
, "span.green". Dilakukan dengan cara ini tidak masalah ketika rentang anak itu dibuat, mengklik pada mereka masih akan menjalankan pawang.Jadi untuk halaman yang tidak menambahkan atau mengubah isinya secara dinamis, Anda tidak akan melihat perbedaan antara kedua metode. Jika Anda secara dinamis menambahkan elemen anak tambahan, sintaks kedua berarti Anda tidak perlu khawatir tentang menetapkan penangan klik kepada mereka karena Anda sudah melakukannya sekali pada orangtua.
sumber
Penjelasan N3dst4 sempurna. Berdasarkan ini, kita dapat mengasumsikan bahwa semua elemen anak berada di dalam tubuh, oleh karena itu kita hanya perlu menggunakan ini:
Ini bekerja dengan acara langsung atau mendelegasikan.
sumber
$('body').on()
delegasi dari.element
harus berperilaku persis sama dengan aslidocument.body.addEventHandler()
denganif (Event.target.className.matches(/\belement\b/))
panggilan balik. Mungkin sedikit lebih lambat dalam jquery karena$.proxy
overhead tetapi jangan mengutip saya tentang itu.Bersinggungan dengan OP, tetapi konsep yang membantu saya mengungkap kebingungan dengan fitur ini adalah bahwa elemen yang terikat haruslah orang tua dari elemen yang dipilih .
.on
..on()
.Delegasi tidak berfungsi seperti .find (), memilih subset dari elemen yang terikat. Selektor hanya berlaku untuk elemen anak yang ketat.
sangat berbeda dari
Secara khusus, untuk mendapatkan keuntungan @ N3dst4 mengisyaratkan dengan "elemen yang dibuat di masa depan" elemen terikat haruslah induk tetap . Kemudian anak-anak yang dipilih dapat datang dan pergi.
EDIT
Daftar periksa mengapa yang didelegasikan
.on
tidak berfungsiAlasan rumit mengapa
$('.bound').on('event', '.selected', some_function)
mungkin tidak berfungsi:.on()
.stopPropagation()
.(Menghilangkan alasan yang tidak terlalu rumit, seperti pemilih yang salah eja.)
sumber
Saya melakukan posting dengan perbandingan acara langsung dan didelegasikan. Saya membandingkan js murni tetapi memiliki arti yang sama untuk jquery yang hanya merangkumnya.
Kesimpulannya adalah bahwa penanganan acara yang didelegasikan adalah untuk struktur DOM dinamis di mana elemen terikat dapat dibuat saat pengguna berinteraksi dengan halaman (tidak perlu lagi mengikat), dan penanganan kejadian langsung adalah untuk elemen DOM statis, ketika kita tahu bahwa struktur tidak akan berubah.
Untuk informasi lebih lanjut dan perbandingan lengkap - http://maciejsikora.com/standard-events-vs-event-delegation/
Menggunakan selalu penangan yang didelegasikan, yang saya lihat saat ini sangat trendi bukan cara yang benar, banyak programmer menggunakannya karena "itu harus digunakan", tetapi kebenarannya adalah penangan kejadian langsung lebih baik untuk beberapa situasi dan pilihan yang menggunakan metode harus didukung dengan pengetahuan tentang perbedaan.
sumber