| الحدث | يحدث عند |
|---|---|
| click | الضغط على عنصر |
| input | تغيير قيمة حقل نص فوراً |
| submit | إرسال نموذج |
| keydown / keyup | الضغط/الرفع عن مفتاح |
| load | اكتمال تحميل الصفحة أو مورد |
الأحداث (Events) هي إشارات يُطلقها المتصفح عند حدوث شيء معين — ضغطة زر، تمرير الفأرة، إرسال نموذج، تحميل صفحة، أو حتى الضغط على مفتاح لوحة المفاتيح. للاستجابة لهذه الأحداث، تستخدم addEventListener() الذي يربط دالة (تُسمى Handler أو Callback) بعنصر معين، بحيث تُستدعى تلقائياً كلما حدث ذلك الحدث المحدد.
تقبل addEventListener() ثلاثة وسائط: نوع الحدث كنص (مثل "click" أو "submit" أو "keydown")، والدالة التي ستُنفَّذ عند الحدث، وخيارات إضافية اختيارية. الميزة الكبرى لـ addEventListener مقارنة بالطرق القديمة (مثل onclick المباشر في HTML) هي إمكانية ربط أكثر من مستمع واحد لنفس الحدث على نفس العنصر دون أن يُلغي أحدهما الآخر.
عند استدعاء دالة الحدث، تُمرَّر لها تلقائياً كائن يُسمى Event، ويحتوي معلومات مهمة عن الحدث نفسه: target للإشارة للعنصر الذي وقع عليه الحدث فعلياً، وpreventDefault() لمنع السلوك الافتراضي للمتصفح (مثل منع إعادة تحميل الصفحة عند إرسال نموذج، أو منع فتح رابط)، وstopPropagation() لإيقاف انتشار الحدث لمكونات الصفحة الأخرى.
مفهوم مهم جداً هنا هو "انتشار الحدث" (Event Bubbling) — عندما يقع حدث على عنصر داخلي، فإنه "يصعد" تلقائياً ليُفعّل نفس نوع الحدث على كل العناصر الأب المحيطة به أيضاً، ما لم تُوقفه بـ stopPropagation. تُستغل هذه الخاصية في تقنية تُسمى "تفويض الأحداث" (Event Delegation)، حيث تضع مستمع حدث واحداً على عنصر أب (كقائمة كاملة) بدلاً من وضع مستمع منفصل على كل عنصر ابن (كل عنصر قائمة)، وهذا يُحسّن الأداء بشكل كبير خاصة مع العناصر الديناميكية المُضافة لاحقاً.
| 1 | const زر = document.querySelector("#submitBtn"); |
| 2 | |
| 3 | زر.addEventListener("click", function (حدث) { |
| 4 | console.log("تم الضغط!", حدث.target); |
| 5 | }); |
| 6 | |
| 7 | // إيقاف السلوك الافتراضي (مثل إرسال نموذج) |
| 8 | نموذج.addEventListener("submit", (حدث) => { |
| 9 | حدث.preventDefault(); |
| 10 | }); |
مثال 1: أحداث شائعة: input, keydown, load
| 1 | // أحداث شائعة مختلفة |
| 2 | const مربع_نص = document.querySelector("#search"); |
| 3 | |
| 4 | مربع_نص.addEventListener("input", (حدث) => { |
| 5 | console.log("القيمة الحالية:", حدث.target.value); |
| 6 | }); |
| 7 | |
| 8 | document.addEventListener("keydown", (حدث) => { |
| 9 | if (حدث.key === "Enter") console.log("تم الضغط على Enter"); |
| 10 | }); |
| 11 | |
| 12 | window.addEventListener("load", () => { |
| 13 | console.log("اكتمل تحميل الصفحة بالكامل"); |
| 14 | }); |
مثال 2: تفويض الأحداث للعناصر الديناميكية
| 1 | // تفويض الأحداث (Event Delegation) — مستمع واحد بدل عشرات |
| 2 | const القائمة = document.querySelector("#todoList"); |
| 3 | |
| 4 | القائمة.addEventListener("click", (حدث) => { |
| 5 | if (حدث.target.matches(".delete-btn")) { |
| 6 | حدث.target.closest("li").remove(); |
| 7 | } |
| 8 | }); |
| 9 | // يعمل حتى مع عناصر li تُضاف لاحقاً بشكل ديناميكي! |