Suatu saat saya sedang bekerja dengan proyek yang banyak melibatkan binding event ke banyak element dinamis. Maksud saya adalah element yang tercipta dari interaksi user seperti dari penggunaan appendChild. Seperti diketahui bahwa saat dokumen HTML dan JavaScript nya selesai terunduh dari server, peraba dari pengguna akan membind event handler hanya ke element yang ada saat itu, yaitu element yang terdapat pada saat dokumen terunduh. Jadi event handler hanya akan dibind sekali pada satu waktu. Jika tercipta elemen baru hasil manipulasi DOM dari interaksi pengguna maka jangan heran jika elemen baru dengan class sama tidak ditangani oleh event handler yang sudah Anda tulis. Untuk lebih jelasnya mari lihat kode JavaScript (dengan jQuery) berikut:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $(function() { var counter = 0; $(".taut").click(function() { var txt = $(this).text(); $("#container-dinamis").append("<div class='dinamis'>Hasil dari click " + txt + "<div>"); }); $("#tambah-taut").click(function() { counter += 1; $("#container-taut").append("<a href='#' title='taut' class='taut'>Aku taut baru yang ke-" + counter + "</a>"); }); }); |
Untuk melihat halaman demonya silahkan klik disini. Saat anchor dengan class taut dihasilkan dari klik #tambah-taut, anchor baru tersebut tidak akan mendapatkan event handler click. Karena event handler click pada element anchor dengan class taut hanya diberikan ke elemen saat baru terunduh. Masalahnya adalah bagaimana agar elemen baru dengan class taut tersebut mendapatkan penanganan yang sama saat terjadi event click? Mari kita lihat solusinya di bawah, yaitu dengan apa yang disebut delegasi event.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $(function() { var counter = 0; $("#container-taut").click(function(e) { var el = $(e.target); var txt = el.text(); if (el.hasClass('taut') { $("#container-dinamis").append("<div class='dinamis'>Hasil dari click " + txt + "<div>"); } }); $("#tambah-taut").click(function() { counter += 1; $("#container-taut").append("<a href='#' title='taut' class='taut'>Aku taut baru yang ke-" + counter + "</a>"); }); }); |
Untuk melihat halaman demo solusi silahkan klik disini. Delegasi event hanyalah pemanfaatan fase event dalam JavaScript, yaitu saat fase event bubbling. Event JavaScript tereksekusi dalam dua fase, yaitu capturing dan bubbling. Saat event terjadi pada element, misal element anchor dengan class taut terklik maka fase capturing dimulai dengan click handler pada dokumen, turun ke <body>, ke <div id="container-taut"> dan akhirnya <a class="taut">. Setelah selesai eksekusi event kembali lagi ke atas (bubbling) sesuai urutan DOM sebelumnya, yaitu <div id="container-taut">, <body> dan document. Semua event handler tereksekusi sesuai urutan fase tersebut. Untuk lebih jelasnya lihat gambar berikut:
Dua fase event JavaScript, capturing dan bubbling, ada karena perbedaan antara implementasi event pada IE dan Netscape dulu (awal mulainya perang browser). IE mendefinisikan event bubbling, sedangkan netscape mendefinisikan event capturing. Lalu W3C menengahkan keduanya dengan mendefinisikan event capturing terjadi pertama kali sampai target element ditemui lalu event akan bubbling ke element parentnya. Model binding event oleh W3C ini adalah addEventListener(). Ada dua model binding event sebelumnya, yaitu model inline dan tradisional. Model inline merupakan model yang dibuat oleh Netscape, yaitu event handler didefinisikan sebagai atribut dari suatu element, misal : <a href="index.html" onclick="alert('yeah')">. Sedangkan model tradisional adalah model yang digunakan sejak netscape 3 dan IE 4 yaitu dengan meregistrasi event handler melalui DOM scripting,
document.getElementById("element").onclick = someFunction;
Event binding di jQuery merupakan W3C model, addEventListener, tanpa event capturing. Untuk melihat bagaimana event bubbling terjadi, perhatikan struktur HTML pada gambar fase event diatas, setiap element memiliki event handler onclick, lalu pada saat element anchor mendapatkan dirinya diklik, event handler untuknya akan dieksekusi, lalu bubbling ke atas mengeksekusi event handler dari element container hingga document. Demo nya dapat di lihat disini.
Dengan mengetahui sifat event seperti ini, event dapat didelegasikan ke element dalam element. Dengan meregistrasi event handler ke element container, anak element dapat ditangani melalui properti target dari objek event. Ya, dalam JavaScript event merupakan objek yang memiliki properti, seperti type, target, keyCode dan sebagainya. Pembahasan event lebih dalam akan saya bahas lain kali. Yang perlu Anda ketahui adalah penggunaan event delegation sangat berguna menghemat handler yang diberikan ke element. Bila Anda bekerja dengan dokumen yang melibatkan banyak element, event delegation memberikan performa lebih baik dibanding dengan membinding setiap element.
Referensi:
- Event Delegation versus Event Handling
- Event order
- Pro JavaScript Techniques oleh John Resig

Bang Gedex,
Bisa beritahu saya apa alasan harus hati hati menggunakan MouseOver dan MouseOut ? (mohon dijelaskan dengan contoh)
Terima kasih atas kesediaan bang gedex menjawab peranyaan dari saya dalam pembelajaran JQuery ini.
#herman
maksud dari author adalah berhati-hati terhadap penanganan event bubbling, khususnya untuk event mouserover dan mouseout. Seperti saya jelaskan di atas untuk mentargetkan ke spesifik elemen saja, dapat digunakan properti dari objek event, misal event.target. Objek event sendiri itu merupakan objek yang dilempar ke fungsi event handler sebagai parameter.
Side Effects of Event Bubbling
Event bubbling can cause unexpected behavior, especially when the wrong element responds to a mouseover or mouseout. Consider a mouseout event handler attached to the in our example. When the user’s mouse cursor exits the , the mouseout handler is run as anticipated. Since this is at the top of the hierarchy, no other elements get the event. On the other hand, when the cursor exits the <a> element, a mouseout event is sent to that. This event will then bubble up to the and then to the , firing the same event handler. This bubbling sequence is likely not desired; for the buttons in our style switcher example, it could mean the highlight was turned off prematurely.
The .hover() method is aware of these bubbling issues, and when we use that method to attach events, we can ignore the problems caused by the wrong element getting a mouseover or mouseout event. This makes .hover() a very attractive alternative to binding the individual mouse events.
Kutipan dari buku Learning JQuery – Better Interaction Design and Web Development
#herman
side efek bagaimana ya? Saya rasa justru penggunaannya lebih baik dari rebinding event. Coba paste disini tulisan dari buku tersebut
Bang gedex, herman mau bertanya.
Saya membaca buku JQuery dan disana dikatakan bahwa Event Bubbling mempunyai masalah (side effects) tetapi saya belum mengerti secara pasti.
bisakah dijelaskan ?
#mul14
bukan, itu hanyalah selector, meskipun benar menselect element berdasarkan #id lebih cepat dari menselect berdasar nodeName. Yang saya maksud adalah penggunaan properti target dari object event.
Jadi ini maksudnya pake $(‘a’).click() lebih baik daripada $(‘a#menu1′).click() ??
Bisa lebih diperjelas?
#Ken
Bahasa Indonesia
What language is this? I thought it was German but Google and Yahoo don’t think so.
Hi…this kind of topic is not common for kiddo web programmer. But I love it. I’m still learning jQuery also. (thanks to google for translate everything)