0Pricing
JavaScript Academy · درس

مرحلتا الالتقاط والانتشار

افهموا كيفية انتقال الأحداث عبر DOM.

مرحلتا الالتقاط والانتشار درس مجاني في JavaScript Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في JavaScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة JavaScript Academy 4 دروس في المجموع.

رحلتان عبر DOM

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

<div id="outer">
  <button id="inner">Click</button>
</div>

الإعداد الافتراضي: الفقاعات

تصغي addEventListener افتراضيًا أثناء مرحلة الفقاعات. فعند النقر فوق الزر الداخلي، يعمل المعالج الخاص به أولًا، ثم المعالج الموجود في العنصر الأب، ثم معالج الجد، وهكذا صعودًا حتى document.

inner.addEventListener("click", () => console.log("inner"));
outer.addEventListener("click", () => console.log("outer"));
// Click inner -> logs: "inner" then "outer"

تفعيل الالتقاط

مرّر وسيطًا ثالثًا قيمته true (أو { capture: true }) للتصغي بدلًا من ذلك أثناء مرحلة الالتقاط. تعمل معالجات الالتقاط من الأعلى إلى الأسفل قبل أي معالجات للفقاعات.

outer.addEventListener("click", () => console.log("outer capture"), true);
inner.addEventListener("click", () => console.log("inner bubble"));
// Click inner -> "outer capture" then "inner bubble"

الترتيب الكامل

عند النقر فوق #inner مع وجود معالجات في كلتا المرحلتين، يكون الترتيب كما يلي: مرحلة الالتقاط من الأعلى إلى الأسفل، ثم الهدف، ثم مرحلة الفقاعات من الأسفل إلى الأعلى.

  • التقاط document
  • التقاط outer
  • inner (الهدف)
  • فقاعات outer
  • فقاعات document

event.target مقابل event.currentTarget

يمثل event.target العنصر الذي أطلق الحدث فعليًا (حيث حدث النقر). أما event.currentTarget فيمثل العنصر الذي يعمل مستمعه حاليًا. ويختلفان في معالج أب يتلقى الحدث عبر الفقاعات.

outer.addEventListener("click", (e) => {
  console.log(e.target.id);        // "inner" - where click occurred
  console.log(e.currentTarget.id); // "outer" - listener owner
});

إيقاف الانتشار

يوقف event.stopPropagation() رحلة الحدث: فلن ينتقل الحدث إلى العنصر التالي في المرحلة الحالية. ولن تعمل معالجات العناصر الأب الأعلى في الشجرة.

inner.addEventListener("click", (e) => {
  e.stopPropagation();
  console.log("handled here only");
});
outer.addEventListener("click", () => console.log("never runs"));

stopImmediatePropagation

تسمح stopPropagation() باستمرار تشغيل المستمعات الأخرى على العنصر نفسه. ولحظر المستمعات الشقيقة أيضًا على العنصر نفسه، استخدم event.stopImmediatePropagation().

inner.addEventListener("click", (e) => {
  e.stopImmediatePropagation();
  console.log("first only");
});
inner.addEventListener("click", () => console.log("blocked"));

يختلف preventDefault

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

link.addEventListener("click", (e) => {
  e.preventDefault();  // do not navigate
  // event still bubbles to parents
});

لماذا نادرًا ما تُستخدم مرحلة الالتقاط

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

التحقق من المرحلة

تخبرك event.eventPhase بالمرحلة النشطة: 1 للالتقاط، و2 عند الهدف، و3 للانتشار صعودًا. نادرًا ما تحتاج إلى ذلك، لكنه مفيد عند تصحيح سلاسل المستمعات المعقدة.

el.addEventListener("click", (e) => {
  console.log(e.eventPhase); // 1, 2, or 3
}, true);

ليست كل الأحداث منتشرة صعودًا

تنتشر معظم أحداث واجهة المستخدم (click وinput وkeydown) صعودًا. لكن بعضها لا ينتشر افتراضيًا، مثل focus وblur وmouseenter. استخدم مع هذه الأحداث النسخ التي تنتشر صعودًا (focusin وfocusout) أو استخدم مرحلة الالتقاط.

تحقق سريع

اختبر مدى فهمك لمراحل الأحداث.

مراجعة

تنتقل الأحداث في مرحلة الالتقاط (إلى الأسفل)، ثم في مرحلة الانتشار صعودًا (إلى الأعلى). يستخدم المستمعون الانتشار صعودًا افتراضيًا؛ مرّر true لاستخدام الالتقاط. يشير e.target إلى مصدر الحدث، بينما يشير e.currentTarget إلى مالك المستمع. استخدم stopPropagation() لإيقاف انتقال الحدث، وpreventDefault() لإلغاء الإجراءات الافتراضية. تشكل هاتان المرحلتان الأساس لتفويض الأحداث.

الأسئلة الشائعة

هل درس «مرحلتا الالتقاط والانتشار» مجاني؟

نعم — نص درس «مرحلتا الالتقاط والانتشار» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة JavaScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة JavaScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «مرحلتا الالتقاط والانتشار»؟

افهموا كيفية انتقال الأحداث عبر DOM. تتمرن على JavaScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ JavaScript Academy؟

لا تُشترط خبرة سابقة. JavaScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «مرحلتا الالتقاط والانتشار»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس JavaScript Academy هذا؟

نعم. كل درس في JavaScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مرحلتا الالتقاط والانتشار
  2. نمط تفويض الأحداث
  3. القوائم الديناميكية مع التفويض
  4. الأحداث المخصصة
← العودة إلى JavaScript Academy