javascriptEvent propagationانتشار رویداد در جاوااسکریپت
انتشار رویداد در جاوااسکریپت را با capture و bubbling ببینید؛ ترتیب اجرای شنوندهها، واگذاری رویداد و تفاوت توقف انتشار با لغو رفتار پیشفرض.
مفهوم به زبان ساده
در یک رابط، دکمه ممکن است داخل کارت و کارت داخل فهرست باشد. رویدادهای زیادی فقط به عنصر آغازگر محدود نمیمانند و در مسیر والدها نیز قابل مشاهدهاند. مرحلهٔ capture از بیرون به سمت هدف حرکت میکند؛ سپس نوبت هدف است و برای رویداد دارای bubbles، مرحلهٔ حبابی از هدف به سمت والدها ادامه مییابد. هر نوع رویداد الزاماً حبابی نیست.
در مثال، سه شنونده روی یک والد و فرزند مستقل ثبت میکنیم. شنوندهٔ والد با capture: true زودتر اجرا میشود؛ سپس شنوندهٔ خود دکمه و در پایان شنوندهٔ معمول والد پیام میدهند. برای نتیجهٔ قابل تکرار، یک رویداد با bubbles: true ارسال میکنیم. هیچکدام از این عناصر به صفحهٔ فعلی متصل نشدهاند و شنوندهای روی سند واقعی نصب نمیشود.
واگذاری رویداد یعنی بهجای ثبت شنونده برای تکتک ردیفها، شنوندهٔ والد را داشته باشیم و هدف مناسب را از event پیدا کنیم. در کد واقعی باید محدوده و نوع هدف را بررسی کرد. stopPropagation ادامهٔ مسیر انتشار را محدود میکند، اما رفتار پیشفرض را لغو نمیکند و لزوماً شنوندههای دیگر همان عنصر را متوقف نمیکند. برای تمرین، یک شنوندهٔ حبابی دیگر اضافه کنید و مسیر را پیش از اجرا بنویسید.
کجا به کار میآید؟
- مدیریت رویداد چند ردیف از طریق شنوندهٔ والد
- عیبیابی اجرای چند شنونده پس از یک تعامل
از تعریف تا یک مثال واقعی
const panel = document.createElement('section');
const button = document.createElement('button');
button.type = 'button';
panel.append(button);
panel.addEventListener('lesson', () => console.log('والد: capture'), { capture: true });
button.addEventListener('lesson', () => console.log('هدف'));
panel.addEventListener('lesson', () => console.log('والد: bubble'));
button.dispatchEvent(new Event('lesson', { bubbles: true }));
والد: capture هدف والد: bubble
این مثال چطور کار میکند؟
گزینهٔ capture شنوندهٔ نخست والد را در مسیر رفت فعال میکند.
رویداد به دکمه میرسد و شنوندهٔ هدف اجرا میشود.
به دلیل bubbles: true، شنوندهٔ حبابی والد در مسیر برگشت اجرا میشود.
اشتباه رایج
stopPropagation جای preventDefault نیست. استفادهٔ بیدلیل از توقف انتشار نیز ممکن است شنوندههای لازم والد، مانند ثبت تعامل یا مدیریت فهرست، را از کار بیندازد.
این را به خاطر بسپارید
مسیر رسیدن رویداد و ترتیب شنوندهها را بدانید؛ فقط عنصری که کلیک شده تعیینکنندهٔ همهٔ رفتارها نیست.