Pengendali Acara JavaScript - Cara Menangani Acara di JS

Apa itu acara?

Peristiwa adalah tindakan yang berlaku ketika pengguna berinteraksi dengan halaman - seperti mengklik elemen, menaip medan, atau memuat halaman.

Penyemak imbas memberitahu sistem bahawa sesuatu telah berlaku, dan perlu ditangani. Ia dikendalikan dengan mendaftarkan fungsi, disebut event handler, yang mendengarkan jenis peristiwa tertentu.

Apa maksudnya "menangani acara"?

Secara ringkas, pertimbangkan ini - anggap anda berminat untuk menghadiri acara perjumpaan Pembangunan Web di komuniti setempat anda.

Untuk melakukan ini, anda mendaftar untuk mengadakan perjumpaan tempatan yang disebut "Women Who Code" dan melanggan pemberitahuan. Dengan cara ini, bila-bila masa perjumpaan baru dijadualkan, anda akan dimaklumkan. Itulah pengendalian acara!

"Acara" di sini adalah perjumpaan JS baru. Apabila perjumpaan baru diposkan, laman web meetup.com dapat melihat perubahan ini, sehingga "menangani" acara ini. Ini kemudian memberi tahu anda, sehingga mengambil "tindakan" pada acara tersebut.

Dalam penyemak imbas, acara ditangani secara serupa. Penyemak imbas mengesan perubahan, dan memberi amaran kepada fungsi (pengendali acara) yang sedang mendengar peristiwa tertentu. Fungsi-fungsi ini kemudian melakukan tindakan seperti yang dikehendaki.

Mari lihat contoh clickpengendali acara:

 Press 1 Press 2 Press 3 const buttonContainer = document.querySelector('.buttons'); console.log('buttonContainer', buttonContainer); buttonContainer.addEventListener('click', event => { console.log(event.target.value) }) 

Apakah pelbagai jenis acara?

Peristiwa boleh dicetuskan setiap kali pengguna berinteraksi dengan halaman. Acara ini boleh menjadi pengguna yang menelusuri halaman, mengklik item, atau memuat halaman.

Berikut adalah beberapa peristiwa biasa - onclickdblclickmousedownmouseupmousemovekeydownkeyuptouchmovetouchstarttouchendonloadonfocusonbluronerror onscroll

Fasa peristiwa yang berbeza - tangkapan, sasaran, gelembung

Apabila suatu peristiwa bergerak melalui DOM - sama ada menggelegak atau turun - ia dipanggil penyebaran peristiwa. Acara menyebarkan melalui pokok DOM.

Kejadian berlaku dalam dua fasa: fasa menggelegak dan fasa penangkapan.

Dalam fasa penangkapan, juga disebut fasa menetes, acara "turun ke bawah" ke elemen yang menyebabkan peristiwa itu.

Ia bermula dari elemen peringkat akar dan pengendali, dan kemudian menyebarkan ke elemen. Fasa penangkapan selesai apabila acara sampai ke target.

Dalam fasa gelembung, acara "digelegak" hingga ke pohon DOM. Ini pertama kali ditangkap dan dikendalikan oleh pengendali paling dalam (yang paling dekat dengan elemen di mana peristiwa itu berlaku). Ia kemudian menggelembung (atau merebak ke atas) ke tingkat pokok DOM yang lebih tinggi, lebih jauh ke ibu bapanya, dan akhirnya ke akarnya.

Ini adalah muslihat untuk membantu anda mengingati perkara ini:

trickle down, bubble up 

Inilah infografik dari quirksmode yang menerangkannya dengan baik:

 / \ ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 | | | | | ------------------------- | | Event BUBBLING | ----------------------------------- | | ---------------| |----------------- | element1 | | | | -----------| |----------- | | |element2 \ / | | | ------------------------- | | Event CAPTURING | ----------------------------------- 

Satu perkara yang perlu diperhatikan ialah, sama ada anda mendaftar pengendali acara dalam kedua fasa, kedua-dua fasa SELALU berlaku. Semua acara dilancarkan secara lalai.

Anda boleh mendaftarkan pengendali acara untuk fasa, menggelegak atau menangkap, dengan menggunakan fungsi addEventListener(type, listener, useCapture). Sekiranya useCaptureditetapkan false, pengendali acara berada dalam fasa menggelegak. Jika tidak, ia berada dalam fasa tangkapan.

Urutan fasa acara bergantung pada penyemak imbas.

Untuk memeriksa penghormatan penyemak imbas mana yang pertama, anda boleh mencuba kod berikut di JSfiddle:

Child One

const childOne = document.getElementById("child-one"); const childOneHandler = () => { console.log('Captured on child one') } const childOneHandlerCatch = () => { console.log('Captured on child one in capture phase') } childOne.addEventListener("click", childOneHandler); childOne.addEventListener("click", childOneHandlerCatch, true); 

Di Firefox, Safari, dan Chrome, outputnya adalah seperti berikut:

Acara dalam fasa tangkapan dilancarkan terlebih dahulu

Cara mendengar acara

Terdapat dua cara untuk mendengar acara:

  1. addEventListener
  2. acara sebaris, seperti onclick
//addEventListener document.getElementByTag('a').addEventListener('click', onClickHandler); //inline using onclick Click me 

Mana yang lebih baik - acara sebaris atau addEventListener?

  1. addEventListener memberi anda kemampuan untuk mendaftar pengendali acara tanpa had.
  2. removeEventListener juga boleh digunakan untuk membuang pengendali acara
  3. The useCapturebendera boleh digunakan untuk menunjukkan sama ada acara perlu ditangani dalam fasa tangkap atau fasa dibundel.

Contoh kod dan aksi langsung

Anda boleh mencuba acara ini di JSFiddle untuk bermain-main dengan mereka.

Child One

Child Two

const wrapperDiv = document.getElementById("wrapper-div"); const childOne = document.getElementById("child-one"); const childTwo = document.getElementById("child-two"); const childOneHandler = () => { console.log('Captured on child one') } const childTwoHandler = () => { console.log('Captured on child two') } const wrapperDivHandler = () => { console.log('Captured on wrapper div') } const childOneHandlerCatch = () => { console.log('Captured on child one in capture phase') } const childTwoHandlerCatch = () => { console.log('Captured on child two in capture phase') } const wrapperDivHandlerCatch = () => { console.log('Captured on wrapper div in capture phase') } childOne.addEventListener("click", childOneHandler); childTwo.addEventListener("click", childTwoHandler); wrapperDiv.addEventListener("click", wrapperDivHandler); childOne.addEventListener("click", childOneHandlerCatch, true); childTwo.addEventListener("click", childTwoHandlerCatch, true); wrapperDiv.addEventListener("click", wrapperDivHandlerCatch, true); 

TL; DR

Fasa acara adalah tangkapan (DOM -> target), gelembung (target-> DOM) dan sasaran.

Acara boleh didengar dengan menggunakan addEventListeneratau kaedah sebaris seperti onclick.

 addEventListener can add multiple events, whereas with onclick this cannot be done. onclick can be added as an HTML attribute, whereas an addEventListener can only be added within  elements. addEventListener can take a third argument which can stop the event propagation. 

Bacaan selanjutnya

//www.quirksmode.org/js/events_order.html

//jsfiddle.net/r2bc6axg/

//stackoverflow.com/questions/6348494/addeventlistener-vs-onclick

//www.w3.org/wiki/HTML/Attributes/_Global#Event-handler_Attributes

Untuk mengikuti tutorial ringkas seperti ini, daftarlah ke buletin saya atau ikuti saya di Twitter