از سال 1393 به برنامه نویسی علاقه مند شدم. اینجا سعی میکنم هر مطلبی که برام جذابه بنویسم و با شما به اشتراک بذارم
Event Capturing و Event Bubbling در جاوااسکریپت
داستان از اونجا شروع شد که میخواستم یه Modal بنویسم و میخواستم زمانی که این Modal باز بود یه پس زمینه تیره داشته باشیم و اگر روی باکس Modal کلیک شد بتونم روی دکمه OK کلیک کنم و اگر روی پس زمینه تیره کلیک کردم این Modal بسته بشه به همین سادگی :)
در جاوا اسکریپت یه مفهومی به اسم Event Flow وجود داره که ترتیب کلیک شدن روی المنت هارو مدیریت میکنه و دو حالت Event Capturing و Event Bubbling داره در حالت پیش فرض روی Event Bubbling قرار داره و به این صورته که از داخلی ترین فرزند، Event شروع به انتشار میکنه و تا بالا ترین والد ادامه پیدا میکنه
مثلا فرض کنید قطعه کد زیر رو داریم:
<div id="modalWrapper">
<button id="modal">click me</button>
</div>
let parent = document.querySelector('#modalWrapper');
parent.addEventListener('click', ()=>{
console.log("Parent clicked");
});
let child = document.querySelector('#modal');
child.addEventListener('click', ()=>{
console.log("Child clicked");
});
در این کد به ترتیب المنت های زیر رو داریم
button , div , body , html , document , window
و با کلیک روی click me به ترتیب از داخلی ترین فرزند یعنی button ایونت ها صدا زده میشن و خروجی این کد میشه
// Child clicked
// Parent clicked
و اگر بخوایم این ترتیب رو برعکس کنیم باید از آرگومان سوم addEventListener که مقدار boolean میگیره که خیلی ها از جمله خود من تا چند وقت پیش کاربردشو نمیدونستم استفاده کنیم :)
این مقدار به صورت پیشفرض برابر با false هستش و اگر این مقدار رو برابر true قرار بدیم ترتیب صدا شدن ایونت ها برعکس میشه و از خارجی ترین والد به سمت داخلی ترین فرزند حرکت میکنه
<div id="modalWrapper">
<button id="modal">click me</button>
</div>
let parent = document.querySelector('#modalWrapper');
parent.addEventListener('click', ()=>{
console.log("Parent clicked");
},true);
let child = document.querySelector('#modal');
child.addEventListener('click', ()=>{
console.log("Child clicked");
},true);
در نتیجه به ترتیب المنت های زیر رو داریم
window , document , html , body , div , button
و با کلیک روی click me به ترتیب از خارجی ترین والد ایونت ها صدا زده میشن و خروجی این کد میشه
// Parent clicked
// Child clicked
و همچنین اگر بخوایم با صدا شدن یک Event فرایند انتشار سایر Event ها متوقف بشه میتونیم از stopPropagation استفاده کنیم که روش استفاده از این متد به صورت زیر می باشد .
<div id="modalWrapper">
<button id="modal">click me</button>
</div>
let parent = document.querySelector('#modalWrapper');
parent.addEventListener('click', (e)=>{
console.log("Parent clicked");
});
let child = document.querySelector('#modal');
child.addEventListener('click', (e)=>{
console.log("Child clicked");
e.stopPropagation();
});
و نتیجه کد بالا برابر است با
// Child clicked
ممنون که وقت گذاشتی، لطفا هر موردی که از قلم انداختم کامنت کن که به این مقاله اضافه کنم ;)
مطلبی دیگر از این انتشارات
فلاکس چیست و با ریداکس چه تفاوتی دارد؟
مطلبی دیگر از این انتشارات
بهترین منبع یادگیری جاوااسکریپت
مطلبی دیگر از این انتشارات
چگونگی Data Fetching (واکشی دادها) در Nextjs