تنقر كتابة داخل زر، فتجد أن العنصر الذي سجله معالج النقر هو span. قبل تغيير الشيفرة، افصل موضع نشوء الحدث عن العنصر الذي ربطت به المستمع. [1]
تشير target إلى هدف الحدث؛ أما currentTarget فتشير، أثناء تنفيذ المعالج، إلى العنصر الذي سُجل عليه ذلك المعالج. [2]
الخلاصة السريعة
- قد تكون target عنصرًا داخل الزر؛ مكان النقر في البنية هو ما يهم، لا اسم الزر الذي تقصده. [1]
- خلال انتشار النقر إلى الأسلاف، تبقى target نفسها في مثالنا، بينما تتغير currentTarget بحسب المستمع الجاري. [3]
- سجّل المستمع على عنصر معلوم باستخدام addEventListener، واقرأ كائن الحدث الذي يصل إلى دالة المعالجة. [4]
- احفظ مرجع currentTarget داخل المعالج إذا احتجته لاحقًا؛ قراءة الخاصية من الحدث بعد المعالجة تعيد null. [2]
ميّز العنصر المنقور من الزر المحيط
قد تكون target عنصرًا داخل الزر؛ مكان النقر في البنية هو ما يهم، لا اسم الزر الذي تقصده. [1]
في HTML أدناه، يحمل النص المعرّف label، ويحمل الزر save. عندما تنقر النص نفسه تكون target هي span؛ وعندما تنقر حشو الزر خارج النص تصبح button. لذلك، لا تفترض أن target تملك دائمًا السمات التي وضعتها على الزر. نحن نفحص عناصر عادية متداخلة في الصفحة، ولا نعمم المثال على المكوّنات ذات شجرة الظل. [1]
تتبّع المستمع أثناء صعود الحدث
خلال انتشار النقر إلى الأسلاف، تبقى target نفسها في مثالنا، بينما تتغير currentTarget بحسب المستمع الجاري. [3]
يمكن أن يصل النقر إلى مستمع الحاوية مع أنه بدأ في ابنها. لو وضعت مستمعًا على الزر وآخر على الحاوية، فإنهما يقرآن هدف النقر نفسه، لكن كلًا منهما يقرأ نفسه في currentTarget. أما النقر المباشر على فراغ الحاوية فيجعل الخاصيتين تشيران إلى الحاوية. اختلافهما احتمال تفسره البنية، وليس شرطًا ملازمًا لكل حدث. [3]
شغّل مثالًا يسجل الهويتين
سجّل المستمع على عنصر معلوم باستخدام addEventListener، واقرأ كائن الحدث الذي يصل إلى دالة المعالجة. [4]
ضع HTML في صفحة فارغة، ثم أضف JavaScript داخل script بعد هذه العناصر. المستمع مرتبط بالحاوية box، وليس بالزر. انقر النص، ثم حشو الزر، ثم الفراغ داخل الإطار؛ سيعرض السطر الأول معرّف الهدف، فشرطة مائلة، فمعرّف الحاوية. المثال يسجل النقرات محليًا، ولا ينفذ عملية حفظ رغم اسم الزر. [4]
مرّر الشيفرة أفقيًا عند الحاجة.
<div id="box" style="padding:24px;border:2px solid">
<button id="save" type="button" style="padding:16px">
<span id="label">احفظ الملاحظة</span>
</button>
</div>
<pre id="log" dir="ltr"></pre>مرّر الشيفرة أفقيًا عند الحاجة.
const box = document.querySelector("#box");
const log = document.querySelector("#log");
box.addEventListener("click", (event) => {
const owner = event.currentTarget;
log.textContent = event.target.id + " / " + owner.id;
setTimeout(() => {
log.textContent += "\n" + event.currentTarget + " / " + owner.id;
}, 0);
});اقرأ المرجع قبل خروج المعالج
احفظ مرجع currentTarget داخل المعالج إذا احتجته لاحقًا؛ قراءة الخاصية من الحدث بعد المعالجة تعيد null. [2]
يعرض السطر الثاني في المثال null ثم box بعد تشغيل المؤقت. قيمة owner حُفظت قبل انتهاء المعالج؛ لا تجعل كائن الحدث المحفوظ بديلًا عنها. عند نقر النص، ينبغي أن تقرأ أولًا label ثم box، وبعدهما null ثم box في السطر التالي. عند تشخيص سجل متأخر، سجّل القيم المطلوبة في وقت الحدث بدل تفسير null على أنه دليل على غياب المستمع أصلًا. [2]
المصادر ومتابعة القراءة
- MDN: هدف الحدث (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: currentTarget ووقت قراءتها (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: انتشار الأحداث وهويتا العنصر (يفتح في نافذة جديدة)developer.mozilla.org
- MDN: تسجيل مستمع الحدث (يفتح في نافذة جديدة)developer.mozilla.org
أُعدّ هذا المقال بصياغة عربية أصلية بالاستناد إلى المصادر أعلاه، وهو مدخل تمهيدي إلى الموضوع. اقرأ منهجية المحتوى وحدوده.