خب اینجوری باید توضیح بدم که شما وقتی یک div دارید که توی اون یک button هست و روی button یک رویداد کلیک مینویسید، وقتی کاربر روی این button کلیک میکنه در واقع این رویداد فقط روی button انجام نمیشه و ممکنه یکسری اِلمان دیگر (مثلا همون div پدر) رو هم تحت تاثیر قرار بده. به این کار میگن گسترش رویداد یا Event Propagation.
ما کلا دو نوع گسترش رویداد یا Event Propagation داریم رویداد حبابی یا Event Bubbling و رویداد گرفتنی یا Event Capturing
اگر به فارسی معنیش کنیم میشه رویداد حباب یا حبابی، همین نشون میده کارش چیه، یعنی چی؟
یعنی اینکه وقتی شما روی یک اِلمان که داخل یک المان دیگر هست کلیک میکنید این رویداد از داخل به خارج منتشر میشه یعنی از خودش شروع میکنه تا به والد یا پدرش برسه که مثل یک حبابه (وقتی حباب ایجاد میشه اول کوچیکه بعد رفته از درون بزرگ میشه)
به طور مثال اول کلیک خودش رو صدا میزنه بعد شروع میکنه کلیک والد رو صدا زدن.
فرض کنید که این کد رو توی فایل html داریم
اتفاقی که میافته اینه که با کلیک روی button اول alert باتن اتفاق میافته بد alert که روی کلیک div نوشتیم. این میشه Event Bubbling.
این رویداد رو هم اگر به فارسی برگردونم میشه رویداد گرفتن یا گرفتنی (خیلی توی فارسی خوب نمیشه برعکس Event Bubbling)، خب یعنی چی، چیکار میکنه، اگر توی مثال قبل یک پارامتر true به فانکشن addEventListner بدیم میشه Event Capturing، درواقع Event Capturing برعکس Event Bubling میشه یعنی به جای انتشار از داخل از پدر یا والد به فرزند میرسه. به مثالی که در ادامه میزنم توجه کنید تا بگم چجوری عمل میکنه...
قطعه کد زیر رو داخل فایل html بنویسید
حالا خروجی کد وقتی روی button کلیک کنیم میشه:
اول alert اِلمان div اتفاق میافته بد alert خود button که روش کلیک کردیم، یعنی در واقع وقتی روی فرزند که button باشه کلیک کردیم event پدر صدا زده شد. برای جلوگیری از این رویداد ها هم در ادامه توضیح میدم که باید چه کرد.
خب تا اینجا فهمیدیم که چه اتفاق هایی میافته و شاید بیشترمون این مشکل رو با Event Bubbling داشتیم.یعنی روی یک اِلمان فرزند که کلیک میکردیم میرفت رویداد پدر رو هم صدا میزد. بعد میرفتیم سرچ میکردیم و با یک خط کد از وقوع اون جلوگیری میکردیم. مثلا اگر یه درخت (Tree) داشتیم که روی فرزنداش کلیک میکردیم، پدرش هم کلیک میشد. (چقدر توضیح دادم).
بعد از اینکه سرچ میکردیم عموما میرسیدیم به دوتا فانکشن، یکی ()event.preventDefault و دیگری ()event.stopPropagation
البته هر کدوم یه کاری رو انجام میدن که در ادامه براتون کامل توضیح میدم.
وقتی از این فانکش استفاده کنیم مانع از عمل کردن ذاتی اون اِلمان یا اِلمنت میشم، مثلا اگر روی submit یک فرم بذاریم باعث میشه اون فرم کار نکنه یا وقتی روی keydown یک اینپوت بذاریم اون رویداد دیگه کار نمیکنه.
کد بالا به شما یه event رو لاگ میده اما هیچ کاراکتری توی input تایپ یا چاپ نمیشه.
اگر بخواهیم ببینم که ()event.preventDefault روی یک اِلمان اتفاق افتاده با پروپرتی event.defaultPrevented میتونیم متوجه بشیم. یک مقدار boolean برمیگردونه.
اگر از این فانکشن استفاده کنیم باعث میشه Event Propagation دیگه اتفاق نیافته، یعنی تاثیرش رو روی بقیه المان ها نمیذاره، مثلا اگر داشته باشیم.
خب وقتی از این فانکشن بعد از alert استفاده کنیم باعث میشه دیگه alert پدر یا همون div اتفاق نیافته.
خب تفاوت این متد با متد event.stopPropagation() این هست که این متد علاوه بر اینکه از اجرای رویداد پدر جلوگیری میکنه بلکه از اجرای رویداد های مشابه اون اِلمان هم جلوگیری میکنه، خب این یعنی چی؟ یعنی اگر دو جا برای button رویداد click رو نوشتید اون موقع از رخ دادن بقیه رویداد های مشابه (click) هم جلو گیری میکنه. مثلا توی مثال زیر دیگه alert مربوط به کلیک !button clicked again اجرا نمیشه.
Event
Propagation×