معالجات أحداث JavaScript - كيفية التعامل مع الأحداث في JS

ما هي الأحداث؟

الأحداث هي الإجراءات التي تحدث عندما يتفاعل المستخدم مع الصفحة - مثل النقر على عنصر أو الكتابة في حقل أو تحميل صفحة.

يقوم المستعرض بإعلام النظام بحدوث شيء ما وأنه بحاجة إلى التعامل معه. يتم التعامل معها عن طريق تسجيل وظيفة تسمى an event handler، والتي تستمع لنوع معين من الأحداث.

ماذا يعني "التعامل مع حدث"؟

لوضعها بعبارات بسيطة ، ضع في اعتبارك هذا - لنفترض أنك مهتم بحضور أحداث لقاء تطوير الويب في مجتمعك المحلي.

للقيام بذلك ، قم بالتسجيل في لقاء محلي يسمى "Women Who Code" والاشتراك في الإشعارات. بهذه الطريقة ، في أي وقت تتم فيه جدولة لقاء جديد ، سيتم تنبيهك. هذا هو التعامل مع الحدث!

"الحدث" هنا هو لقاء JS جديد. عند نشر لقاء جديد ، يلاحظ موقع الويب meetup.com هذا التغيير ، وبالتالي "يتعامل" مع هذا الحدث. ثم يخطرك ، وبالتالي يتخذ "إجراءً" بشأن الحدث.

في المتصفح ، يتم التعامل مع الأحداث بالمثل. يكتشف المستعرض تغييرًا ، وينبه وظيفة (معالج الحدث) تستمع إلى حدث معين. ثم تقوم هذه الوظائف بتنفيذ الإجراءات حسب الرغبة.

لنلقِ نظرة على مثال clickلمعالج الأحداث:

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

ما هي أنواع الأحداث المختلفة؟

يمكن تشغيل حدث في أي وقت يتفاعل فيه المستخدم مع الصفحة. قد تكون هذه الأحداث عبارة عن مستخدم يقوم بالتمرير عبر الصفحة أو النقر فوق عنصر أو تحميل صفحة.

فيما يلي بعض الأحداث الشائعة - onclickdblclickmousedownmouseupmousemovekeydownkeyuptouchmovetouchstarttouchendonloadonfocusonbluronerror onscroll

مراحل مختلفة من الأحداث - التقاط ، الهدف ، الفقاعة

عندما يتحرك حدث ما عبر DOM - سواء كان يتدفق إلى الأعلى أو يتدفق إلى أسفل - يطلق عليه اسم انتشار الحدث. ينتشر الحدث من خلال شجرة DOM.

تحدث الأحداث على مرحلتين: مرحلة الفقاعة ومرحلة الالتقاط.

في مرحلة الالتقاط ، وتسمى أيضًا بمرحلة التقطير ، يتدفق الحدث إلى العنصر الذي تسبب في حدوث الحدث.

يبدأ من عنصر ومعالج مستوى الجذر ، ثم ينتشر وصولاً إلى العنصر. تكتمل مرحلة الالتقاط عندما يصل الحدث إلى target.

في مرحلة الفقاعة ، يكون الحدث "فقاعات" يصل إلى شجرة DOM. يتم التقاطها ومعالجتها أولاً بواسطة المعالج الأعمق (الأقرب إلى العنصر الذي حدث فيه الحدث). ثم ترتفع الفقاعات (أو تنتشر) إلى المستويات الأعلى من شجرة DOM ، وصولًا إلى الأبوين ، ثم أخيرًا إلى جذرها.

إنها خدعة لمساعدتك على تذكر هذا:

trickle down, bubble up 

إليك مخطط معلومات من quirksmode يشرح هذا جيدًا:

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

شيء واحد يجب ملاحظته هو أنه سواء قمت بتسجيل معالج حدث في أي من المرحلتين ، فإن كلا المرحلتين تحدثان دائمًا. جميع الأحداث فقاعة بشكل افتراضي.

يمكنك تسجيل معالجات الأحداث لأي من الطور ، أو الفقاعة أو الالتقاط ، باستخدام الوظيفة addEventListener(type, listener, useCapture). إذا useCaptureتم التعيين على false، يكون معالج الأحداث في مرحلة الفقاعة. وإلا فهو في مرحلة الالتقاط.

يعتمد ترتيب مراحل الحدث على المتصفح.

للتحقق من التقاط الامتيازات في المتصفح أولاً ، يمكنك تجربة الكود التالي في 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); 

في Firefox و Safari و Chrome ، يكون الإخراج كالتالي:

يتم تشغيل الأحداث في مرحلة الالتقاط أولاً

كيف تستمع إلى حدث

هناك طريقتان للاستماع إلى حدث:

  1. addEventListener
  2. الأحداث المضمنة ، مثل onclick
//addEventListener document.getElementByTag('a').addEventListener('click', onClickHandler); //inline using onclick Click me 

أيهما أفضل - حدث مضمّن أم addEventListener؟

  1. addEventListener يمنحك القدرة على تسجيل معالجات أحداث غير محدودة.
  2. removeEventListener يمكن أيضًا استخدامها لإزالة معالجات الأحداث
  3. و useCaptureالعلم يمكن أن تستخدم للإشارة إلى ما إذا كان الحدث يحتاج إلى التعامل معها في مرحلة اعتقال أو مرحلة واحدة.

أمثلة التعليمات البرمجية والعمل الحي

يمكنك تجربة هذه الأحداث في JSFiddle للتلاعب بها.

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

مراحل الحدث هي الالتقاط (DOM -> target) ، الفقاعة (target-> DOM) والهدف.

يمكن الاستماع إلى الأحداث باستخدام addEventListenerأو طرق مضمنة مثل 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. 

قراءة أخرى

//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

لمواكبة المزيد من البرامج التعليمية القصيرة مثل هذه ، اشترك في رسالتي الإخبارية أو تابعني على Twitter