سلام! در این درس، می خواهم در مورد مفهوم مهمی مانند حباب کردن و رهگیری رویدادها صحبت کنم. حباب پدیده ای است که در آن اگر روی عنصر فرزند کلیک کنید، رویداد به والد آن منتشر می شود.

این می تواند در هنگام پردازش لیست ها یا جداول تودرتوی بزرگ بسیار مفید باشد، برای اینکه یک کنترل کننده رویداد به هر عنصر اختصاص داده نشود، می توانید به ازای هر عنصر یک کنترل کننده را اختصاص دهید. عنصر والد، و رویداد از قبل به همه عناصر تودرتو در والد منتشر می شود. بیایید به یک مثال نگاه کنیم.

این کنترل کننده برای

اگر روی یک تگ تو در تو کلیک کنید کار خواهد کرد یا :

روی EM کلیک کنید، هندلر روی DIV کار خواهد کرد

همانطور که می بینید، وقتی روی عنصر em تو در تو کلیک می کنید، کنترل کننده روی div فعال می شود. چرا این اتفاق می افتد؟ بخوانید و پیدا کنید.

صعود

بنابراین اصل اساسی صعود:

برای هر رویدادی، مهم نیست که ماوس روی عنصر کلیک شود، رویداد ابتدا روی عنصر والد کار می‌کند و سپس در طول زنجیره به همه عناصر تودرتو گسترش می‌یابد.

به عنوان مثال، فرض کنید 3 عنصر تو در تو FORM > DIV > P وجود دارد که روی هر کدام یک کنترلر رویداد وجود دارد:

فرم
DIV

حباب زدن تضمین می کند که عنصر داخلی کلیک می شود

ابتدا کنترل کننده کلیک (اگر وجود داشته باشد) روی آن فراخوانی می شود

چنین فرآیندی حباب نامیده می شود، زیرا رویدادها، همانطور که بود، از عنصر درونی به بالا از طریق والدین خود "شناور" می شوند، درست مانند یک حباب هوا که در آب شناور است، بنابراین می توانید تعریف حباب را نیز پیدا کنید، خوب، فقط از کلمه انگلیسی حباب - شناور کردن.

دسترسی به عنصر هدف event.target

برای اینکه بفهمیم روی کدام عنصر این یا آن رویداد را گرفتیم، روش event.target وجود دارد. (در مورد شی رویداد بخوانید).

  • رویداد.هدف- این خود عنصر اصلی است که رویداد روی آن رخ داده است.
  • این- این همیشه عنصر فعلی است که حباب به آن رسیده است و کنترل کننده در حال حاضر روی آن اجرا می کند.

به عنوان مثال، اگر فقط یک handler form.onclick نصب کرده باشید، تمام کلیک‌های داخل فرم را می‌گیرد. در همان زمان، هر جا که یک کلیک در داخل وجود داشته باشد، همچنان به عنصر ظاهر می شود

، که کنترل کننده روی آن کار خواهد کرد.

که در آن:

  • این(=event.currentTarget) همیشه خود فرم خواهد بود، زیرا کنترل کننده روی آن کار کرده است.
  • رویداد.هدفحاوی پیوندی به یک عنصر خاص در داخل فرم خواهد بود، تودرتوترین عنصر، که کلیک روی آن رخ داده است.

در اصل، اگر روی فرم کلیک شود و عناصر دیگری در فرم وجود نداشته باشد، این می تواند مانند event.target باشد.

توقف صعود

به طور معمول، حباب رویداد مستقیماً به بالا می رود و به شی پنجره ریشه می رسد.

اما می توان صعود را در برخی از عناصر میانی متوقف کرد.

برای توقف حباب زدن، متد event.stopPropagation() را فراخوانی کنید.

بیایید به مثالی نگاه کنیم که در آن با کلیک روی دکمه، هندلر body.onclick کار نخواهد کرد:

اگر عنصر دارای چندین کنترل کننده برای یک رویداد باشد، حتی اگر حباب متوقف شود، همه آنها اجرا می شوند.

بنابراین، stopPropagation از انتشار بیشتر رویداد جلوگیری می‌کند، اما همه کنترل‌کننده‌ها روی عنصر کار خواهند کرد، اما نه بیشتر روی عنصر بعدی.

برای توقف پردازش عنصر فعلی، مرورگرها از متد event.stopImmediatePropagation() پشتیبانی می کنند. این روش نه تنها از ایجاد حباب جلوگیری می کند، بلکه پردازش رویداد را در عنصر فعلی متوقف می کند.

غوطه وری

در استاندارد، علاوه بر "ظهور" رویدادها، "غوطه وری" نیز وجود دارد.

غواصی، بر خلاف صعود، تقاضای کمتری دارد، اما دانستن در مورد آن همچنان مفید خواهد بود.

بنابراین 3 مرحله از رویداد وجود دارد:

  1. این رویداد از بالا به پایین می رود. این مرحله را «مرحله رهگیری» می نامند.
  2. رویداد به عنصر خاصی رسید. این مرحله هدف است.
  3. پس از همه، رویداد شروع به ظاهر شدن می کند. این «مرحله شناور» است.

این در استاندارد به صورت زیر نشان داده شده است:

بنابراین، هنگامی که روی یک TD کلیک می‌شود، رویداد از طریق زنجیره والدین، ابتدا به عنصر ("سینک") و سپس به سمت بالا ("شناور") حرکت می‌کند و کنترل‌کننده‌ها را بر این اساس در طول مسیر فعال می‌کند.

در بالا فقط در مورد صعود نوشتم، چون خود مراحل دیگر مورد استفاده قرار نمی گیرند و مورد توجه ما قرار نمی گیرند.

گردانندگان چیزی در مورد مرحله رهگیری نمی دانند، اما از حباب شروع به کار می کنند.

و برای گرفتن یک رویداد در مرحله رهگیری، فقط باید از موارد زیر استفاده کنید:

  • استدلال درست است، سپس رویداد در راه پایین رهگیری خواهد شد.
  • استدلال نادرست است، پس از حباب کردن، رویداد ضبط می شود.

مثال ها

در مثال در ,

,

همان دسته های قبلی وجود دارد، اما این بار - در مرحله غوطه وری. خوب، برای مشاهده عمل رهگیری، روی عنصر موجود در آن کلیک کنید

کنترل کننده ها به ترتیب از بالا به پایین کار خواهند کرد: FORM → DIV → P.

کد JS به این صورت است:

varelems = document.querySelectorAll("form,div,p"); // روی هر عنصر یک کنترل کننده در مرحله رهگیری برای (var i = 0; i< elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); }


هیچ کس شما را اذیت نمی کند که برای هر دو مرحله کنترل کننده هایی را تعیین کنید، مانند این:

varelems = document.querySelectorAll("form,div,p"); برای (var i = 0; i< elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); elems[i].addEventListener("click", highlightThis, false); }

روی عنصر داخلی کلیک کنید

برای مشاهده ترتیب ارسال یک رویداد:
باید FORM → DIV → P → P → DIV → FORM باشد. توجه داشته باشید که عنصر

در هر دو مرحله شرکت خواهد کرد.

نتایج

  • هنگامی که یک رویداد رخ می دهد، عنصری که رویداد روی آن رخ داده است به عنوان event.target علامت گذاری می شود.
  • رویداد ابتدا از ریشه سند به event.target منتقل می‌شود، و در طول مسیر، کنترل‌کننده‌های ارائه‌شده از طریق addEventListener (….، true) را فراخوانی می‌کند.
  • رویداد از event.target تا ابتدای سند حرکت می‌کند، در طول مسیر، کنترل‌کننده‌های ارائه‌شده از طریق addEventListener (….، false) را فراخوانی می‌کند.

هر کنترل کننده به ویژگی های رویداد دسترسی خواهد داشت:

  • event.target عمیق ترین عنصری است که واقعه روی آن اتفاق افتاده است.
  • event.currentTarget (=this) عنصری است که روی آن این لحظهخودگردان کار کرد (که رویداد "به آن رسید").
  • event.eventPhase - کنترل کننده رویداد در چه مرحله ای شلیک کرد (dive = 1، float = 3).

حباب زدن را می توان با فراخوانی متد event.stopPropagation() متوقف کرد، اما این توصیه نمی شود زیرا ممکن است برای اهداف غیرمنتظره ای به رویداد نیاز داشته باشید.

اکنون به برخی از موارد پیشرفته هنگام کار با شی Event نگاهی خواهیم انداخت، از جمله: حباب زدن و رهگیری، و همچنین تفویض رویداد.

حباب رویداد

تصور کنید که چندین بلوک تودرتو دارید:

درونی ترین بلوک

وقتی روی درونی ترین بلوک یعنی رویداد کلیک می کنید onclickابتدا در آن رخ می دهد، و سپس در والد خود، در والد والد خود، و به همین ترتیب، تا زمانی که به آن برچسب برسد شلیک می شود. بدنو به تگ html(سپس به سندو قبل از پنجره).

و این منطقی است، زیرا با کلیک بر روی بلوک داخلی، به طور همزمان روی تمام بلوک های بیرونی کلیک می کنید.

بیایید این را در مثال زیر ببینیم: ما 3 بلوک داریم که هر کدام یک رویداد onclick به آن متصل است:

روی داخلی ترین بلوک قرمز کلیک کنید - و خواهید دید که چگونه کلیک بلوک قرمز ابتدا، سپس آبی و سپس سبز کار می کند:

این رفتار نامیده می شود روکش کردنرویدادها - به قیاس با صعود یک حباب هوا از پایین. درست مانند حباب، به نظر می رسد که کلیک ما روی عنصر داخلی به سمت بالا شناور است و هر بار در بلوک های بالاتر فعال می شود.

رویداد.هدف

فرض کنید دو عنصر داریم: یک div و یک پاراگراف p که درون این div قرار دارد. بیایید onlick را به یک دیوا گره بزنیم:

وقتی روی این div کلیک می کنیم، می توانیم به یک پاراگراف برویم، یا می توانیم به جایی برویم که این پاراگراف وجود ندارد.

چگونه ممکن است این اتفاق بیفتد - به مثال زیر نگاه کنید: سبز div ما است و آبی پاراگراف ما است:

اگر روی قسمت سبز رنگ کلیک کنید روی div کلیک می کنیم و اگر روی قسمت آبی رنگ کلیک کنید ابتدا روی پاراگراف و سپس روی div کلیک می کنیم. اما از آنجایی که onclick به طور خاص به div متصل است، ما، به طور کلی، ممکن است متوجه حضور پاراگراف نشویم.

با این حال، گاهی اوقات مایلیم بدانیم که آیا کلیک مستقیماً روی div یا پاراگراف اصلی آن اتفاق افتاده است. شی Event و ویژگی آن به ما در این امر کمک می کند. رویداد.هدف- دقیقاً عنصری را که کلیک در آن رخ داده است ذخیره می کند.

در مثال زیر داریم بخش، درون آن نهفته است پو داخل آن - طول.

بیایید رویداد onclick را به بالاترین عنصر (div) متصل کنیم و روی عناصر مختلف کلیک کنیم: div، p، span. با استفاده از رویداد.هدفپایین ترین عنصر را در جایی که رویداد رخ داده است دریافت کنید و نام آن را با استفاده از tagName نمایش دهید.

اگر مثلاً روی span کلیک کنید، رویداد دیو ما را می گیرد (در نهایت، onclick به آن متصل است)، اما در رویداد.هدفدقیقا دروغ خواهد گفت طول:

روی بلوک های مختلف کلیک کنید - نتیجه را خواهید دید:

توقف صعود

بنابراین، شما از قبل می دانید که همه رویدادها به بالاترین سطح (تا تگ htmlو سپس به سند و سپس به پنجره). گاهی اوقات نیاز به توقف این صعود وجود دارد. این کار را می توان توسط هر عنصری که رویداد از طریق آن ظاهر می شود انجام داد. برای انجام این کار، در کد عنصر، متد را فراخوانی کنید event.stopPropagation().

در مثال زیر، کلیک کردن روی بلوک قرمز روی خودش کار می‌کند، سپس روی بلوک آبی و تمام - بلوک آبی صعود بیشتر را متوقف می‌کند و بلوک سبز به هیچ وجه واکنشی نشان نمی‌دهد:

روی بلوک قرمز کلیک کنید - نتیجه را خواهید دید:

غوطه وری

علاوه بر حباب وقایع، وجود دارد شیرجه رفتن(طبق نظر علمی مرحله رهگیری). این بدان معنی است که رویداد ابتدا از بالا به پایین می رود (مرحله رهگیری)، به عنصر ما (مرحله هدف) می رسد و تنها پس از آن شروع به شناور می کند (مرحله حباب).

شما می توانید یک کنترل کننده رویداد را با در نظر گرفتن مرحله رهگیری فقط با کمک آویزان کنید addEventListener. برای انجام این کار، یک پارامتر سوم دارد: اگر برابر با true باشد، رویداد در مرحله رهگیری و اگر نادرست باشد، در مرحله حباب (به طور پیش فرض این است):

Vargreen = document.getElementById("سبز"); green.addEventListener("click", func, true); تابع (رویداد) ( )

مرحله ای که یک رویداد در آن رخ داده را می توان با استفاده از ویژگی تعیین کرد event.eventPhase. این می تواند مقادیر زیر را داشته باشد: 1 - مرحله رهگیری، 2 - مرحله هدف، 3 - مرحله صعود.

مقدمه ای بر نمایندگی

موقعیتی را تصور کنید: اجازه دهید داشته باشیم ulبا چندین لی. رویداد زیر به هر li پیوست می‌شود: وقتی روی li کلیک می‌شود، «!» به انتهای آن اضافه می‌شود.

بیایید موارد بالا را پیاده سازی کنیم:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
var li = document.querySelectorAll("#ul li"); //در حلقه، تابع addSign را روی هر li آویزان می کنیم: for (var i = 0; i

روی li کلیک کنید - خواهید دید که چگونه "!" به انتهای آنها اضافه می شود:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5

بگذارید اکنون یک دکمه نیز داشته باشیم که با کلیک کردن روی آن یک دکمه جدید به انتهای ul اضافه می شود لیبا متن "اقلام". ما در انتظار یک شگفتی هستیم: رویداد پیوست کار نخواهد کرد برای جدیدلی بیایید از این مطمئن شویم:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5

روی دکمه اضافه کردن li و سپس روی این li جدید کلیک کنید - عکس العمل نشان نمی دهد:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
li را اضافه کنید

برای حل مشکل، در زمان ایجاد یک li جدید، یک تابع را روی آن آویزان کنید addSignاز طریق addEventListener. بیایید این را پیاده سازی کنیم:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
var li = document.querySelectorAll("#ul li"); برای (var i = 0; i

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
li را اضافه کنید

راه دومی برای حل مشکل وجود دارد - نمایندگی رویداد. بیایید آن را تحلیل کنیم.

هیئت رویداد

ماهیت تفویض اختیار به شرح زیر است: ما یک رویداد را نه در هر لی، بلکه در والدین آنها خواهیم گذاشت - در ul.

در عین حال، عملکرد اسکریپت ما باید حفظ شود: مانند قبل، با کلیک بر روی li، "!" به انتهای آن اضافه می شود. فقط رویداد در نسخه جدید در ul آویزان خواهد شد:

var ul = document.getElementById("ul"); //رویداد را روی ul آویزان کنید: ul.addEventListener("click", addSign); تابع addSign() ()

چگونه این کار را انجام دهیم: از آنجایی که رویداد روی ul آویزان است، در داخل تابع می توانیم li را با آن بگیریم رویداد.هدف. اجازه دهید یادآوری کنم event.target چیست - این دقیقاً همان برچسبی است که کلیک روی آن اتفاق افتاده است، در مورد ما چنین است. لی.

بنابراین، در اینجا راه حل مشکل ما از طریق تفویض اختیار است:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5

نتیجه اجرای کد:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5

در این صورت راه حل ما به طور خودکار کار خواهد کرد حتی برای لی جدید، زیرا رویداد نه در li، بلکه در ul آویزان است:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
var ul = document.getElementById("ul"); ul.addEventListener("کلیک کنید"، addSign); تابع addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; ) //اجرای دکمه برای افزودن یک li جدید: var button = document.getElementById("button"); button.addEventListener("کلیک کنید"، addLi); تابع addLi() ( var li = document.createElement("li"); li.innerHTML = "li جدید"; ul.appendChild(li); )

روی دکمه اضافه کردن li و سپس روی این li جدید کلیک کنید - واکنش نشان می دهد:

  • بند 1
  • نقطه 2
  • نقطه 3
  • نقطه 4
  • نقطه 5
li را اضافه کنید

کد ما کار می کند، اما بدون نقص نیست. بیایید این کاستی ها را تحلیل کنیم و راه حل جهانی تری بنویسیم.

هیئت رویداد عمومی

نقطه ضعف کد ما زمانی خود را نشان می دهد که برخی تگ های تودرتو در داخل li وجود داشته باشد. در مورد ما، بگذارید برچسب باشد من:

در این مورد، فشار دادن منمنجر به اضافه شدن یک علامت تعجب می شود انتهای i تگ کنید، نه یک برچسب لی، همانطور که می خواهیم (اگر روی li خارج از حروف کج کلیک کنید، همه چیز درست می شود):

  • پاراگراف مورب 1
  • پاراگراف مورب 2
  • پاراگراف مورب 3
  • پاراگراف مورب 4
  • پاراگراف مورب 5
var ul = document.getElementById("ul"); ul.addEventListener("کلیک کنید"، addSign); تابع addSign() ( event.target.innerHTML = event.target.innerHTML + "!"; )

روی حروف کج کلیک کنید - خواهید دید که چگونه "!" به انتهای آن اضافه می شود (فشردن خارج از حروف کج به خوبی کار می کند):

مشکل به صورت زیر برطرف می شود (روش توصیف شده تنها روش نیست، بلکه ساده ترین است): با استفاده از نزدیکترین روش، نزدیکترین li را پیدا می کنیم که والد event.target به این صورت است: event.target.closest("li").

نحوه کار: اگر کلیک روی آن بود من، سپس در رویداد.هدفاین من دروغ می گویم و در event.target.closest("li")- لی ما که برای آن رویداد باید شلیک شود.

اگر کلیک بر روی بود لی، سپس در رویداد.هدف، و در event.target.closest("li")لی ما دروغ خواهد گفت

بیایید بررسی کنیم:

  • پاراگراف مورب 1
  • پاراگراف مورب 2
  • پاراگراف مورب 3
  • پاراگراف مورب 4
  • پاراگراف مورب 5
var ul = document.getElementById("ul"); ul.addEventListener("click", function(event) ( var li = event.target.closest("li"); if (li) ( //بررسی کنید آیا اصلا li والد وجود ندارد li.innerHTML = li.innerHTML + "!" ) )))

نتیجه اجرای کد:

مهم نیست که چقدر عمیق است: برچسب منمی تواند در یک برچسب باشد ب، و یکی در تگ طولو تنها پس از آن در لی- مهم نیست: ساخت و ساز event.target.closest("li")والد را از هر سطح تودرتو پیدا می کند.

هنگامی که یک رویداد رخ می دهد، کنترل کننده ها ابتدا روی خود عنصر تودرتو، سپس روی والد آن، سپس در بالا، و به همین ترتیب، به زنجیره تودرتو شلیک می کنند.

به عنوان مثال، 3 عنصر تو در تو FORM > DIV > P وجود دارد که روی هر کدام یک کنترلر وجود دارد:

کد: فرم

DIV

حباب تضمین می کند که یک کلیک بر روی داخلی

ابتدا با کنترل کننده onclick (در صورت وجود) روی آن تماس می گیرد

بنابراین، اگر در مثال بالا روی P کلیک کنید، هشدار به صورت متوالی نمایش داده می شود: p → div → form.

این فرآیند حباب نامیده می شود زیرا رویدادهایی که از عنصر درونی از طریق والدین به بالا حباب می شوند، بسیار شبیه به شناور شدن حباب هوا در آب است.

رویداد.هدف

با توجه به هر عنصری که رویداد را بگیریم، همیشه می‌توانید دقیقاً محل وقوع آن را پیدا کنید.
عمیق ترین عنصری که رویداد را فعال می کند عنصر "هدف" یا "منبع" نامیده می شود و به عنوان event.target در دسترس است.

تفاوت با این (=event.currentTarget):

  • event.target عنصر منبعی است که رویداد روی آن رخ داده است، در طول فرآیند حباب تغییر نمی کند.
  • این عنصر فعلی است که حباب به آن رسیده است، کنترل کننده در حال حاضر روی آن اجرا می کند.

به عنوان مثال، اگر فقط یک handler form.onclick وجود داشته باشد، تمام کلیک‌های داخل فرم را می‌گیرد. هر جا که یک کلیک در داخل وجود دارد - به عنصر ظاهر می شود

که در آن کنترل کننده اجرا خواهد شد.

که در آن:

  • این (=event.currentTarget) همیشه خود فرم خواهد بود، زیرا کنترل کننده روی آن شلیک کرده است.
  • event.target حاوی پیوندی به یک عنصر خاص در داخل فرم است، تودرتوترین عنصری که روی آن کلیک شده است.

همچنین ممکن است event.target و این همان عنصر باشند، مثلاً اگر تگ دیگری در فرم نباشد و کلیک روی خود عنصر بوده باشد. .

حباب کردن یک رویداد را متوقف کنید

صعود مستقیم به بالا می رود. به طور معمول رویداد تا عنصر حباب می شود و بالا می رود ، و سپس تا سند و گاهی اوقات حتی پنجره، همه کنترل کننده های موجود در مسیر خود را فراخوانی می کند.

اما هر میان افزاری می تواند تصمیم بگیرد که رویداد به طور کامل پردازش شده و حباب را متوقف کند.

برای جلوگیری از حباب زدن، باید متد را فراخوانی کنید event.stopPropagation().

به عنوان مثال، در اینجا، هنگام کلیک بر روی دکمه، هندلر body.onclickکار نخواهد کرد:

کد:

رهگیری رویداد. event.stopImmediatePropagation()

اگر یک عنصر چندین کنترل کننده برای یک رویداد داشته باشد، حتی اگر حباب متوقف شود، همه آنها اجرا می شوند.

به این معنا که، توقف انتشاراز پیشرفت بیشتر رویداد جلوگیری می کند، اما در عنصر فعلی، همه کنترل کننده ها کار خواهند کرد.

برای توقف کامل پردازش، مرورگرهای مدرنروش پشتیبانی event.stopImmediatePropagation(). این نه تنها از ایجاد حباب جلوگیری می کند، بلکه پردازش رویداد را در عنصر فعلی متوقف می کند.

تفاوت های IE8

برای آسان‌تر کردن پیمایش، تفاوت‌های IE8 را که مربوط به حباب‌سازی هستند را در یک بخش جمع‌آوری کرده‌ام.

اگر تصمیم به نوشتن در JS خالص، بدون چارچوب و نیاز به پشتیبانی IE8 دارید، دانش آنها مورد نیاز خواهد بود.

ویژگی event.currentTarget وجود ندارد

توجه داشته باشید که هنگام تخصیص یک handler از طریق ویژگی on، این مورد را داریم، بنابراین event.currentTarget معمولاً مورد نیاز نیست، اما هنگامی که از طریق attachEvent اختصاص داده می شود، کنترل کننده این را دریافت نمی کند، بنابراین عنصر فعلی، در صورت نیاز، فقط می تواند از آن گرفته شود. بسته شدن

Event.srcElement به جای event.target در IE8 استفاده می شود

اگر ما در حال نوشتن یک هندلر هستیم که هم از مرورگرهای IE8 و هم از مرورگرهای مدرن پشتیبانی می‌کند، می‌توانیم آن را به این صورت شروع کنیم:

کد: elem.onclick = تابع (رویداد) (
رویداد = رویداد || window.event;
var target = event.target || event.srcElement;

// ... اکنون یک شی رویداد و یک هدف داریم
...
}

برای توقف حباب از کد event.cancelBubble=true استفاده کنید

می توانید مرورگر متقابل پاپ آپ را به این صورت متوقف کنید:

کد: event.stopPropagation ? event.stopPropagation() : (event.cancelBubble=true);

جمع

  • هنگامی که یک رویداد رخ می دهد، عنصری که روی آن رخ داده است به عنوان "هدف" (event.target) علامت گذاری می شود.
  • در مرحله بعد، رویداد ابتدا از ریشه سند به event.target منتقل می‌شود و کنترل‌کننده‌های ارائه‌شده از طریق addEventListener (...، true) را در طول مسیر فراخوانی می‌کند.
  • سپس رویداد از event.target به سمت ریشه سند حرکت می‌کند و در طول مسیر با کنترل‌کننده‌ها تماس می‌گیرد، که از طریق on* و addEventListener (....، false) ارائه می‌شود.
  • event.target عمیق ترین عنصری است که رویداد روی آن رخ داده است.
  • event.currentTarget (=this) – عنصری که کنترل کننده در حال حاضر روی آن راه اندازی می شود (رویداد به آن شناور می شود).
  • event.eventPhase - در چه مرحله ای کار کرد (شیرجه = 1، صعود = 3).

رویدادها اعمال یا رخدادهایی هستند که در سیستمی که شما برنامه‌نویسی می‌کنید اتفاق می‌افتد و سیستم در مورد آن به شما می‌گوید تو می توانیدر صورت تمایل به نحوی به آنها پاسخ دهید. برای مثال، اگر کاربر روی یک دکمه در یک صفحه وب کلیک کند، ممکن است بخواهید با نمایش یک جعبه اطلاعات به آن عمل پاسخ دهید. در این مقاله، برخی از مفاهیم مهم رویدادهای اطراف را مورد بحث قرار می دهیم و به نحوه عملکرد آنها در مرورگرها می پردازیم. این یک مطالعه جامع نخواهد بود، فقط آنچه در این مرحله باید بدانید.

پیش نیازها: سواد اولیه کامپیوتر، درک اولیه HTML و CSS، اولین قدم های جاوا اسکریپت.
هدف، واقعگرایانه: برای درک نظریه اساسی رویدادها، نحوه کار آنها در مرورگرها، و اینکه چگونه رویدادها ممکن است در محیط های برنامه نویسی مختلف متفاوت باشند.

یک سری اتفاقات خوش شانس

مانند بالا، مناسبت هااعمال یا رخدادهایی هستند که در سیستمی که در حال برنامه‌نویسی آن هستید اتفاق می‌افتد - سیستم زمانی که رویدادی رخ می‌دهد نوعی سیگنال تولید می‌کند (یا "آتش" می‌کند) و همچنین مکانیزمی را فراهم می‌کند که توسط آن نوعی عمل به طور خودکار انجام شود (یعنی ، برخی از کدها در حال اجرا هستند) هنگامی که رویداد رخ می دهد. به عنوان مثال در یک فرودگاه زمانی که باند پرواز برای بلند شدن هواپیما مشخص است، یک سیگنال به خلبان مخابره می شود و در نتیجه، آنها شروع به هدایت هواپیما می کنند.

در مورد وب، رویدادها در داخل پنجره مرورگر اجرا می‌شوند و تمایل دارند به یک آیتم خاص که در آن قرار دارد متصل شوند - این ممکن است یک عنصر واحد، مجموعه‌ای از عناصر، سند HTML بارگیری شده در برگه فعلی یا کل پنجره مرورگر انواع مختلفی از رویدادها ممکن است رخ دهد، به عنوان مثال:

  • کاربر روی یک عنصر خاص کلیک می کند یا مکان نما را روی یک عنصر خاص نگه می دارد.
  • کاربر در حال فشار دادن یک کلید روی صفحه کلید.
  • تغییر اندازه کاربر یا بستن پنجره مرورگر.
  • فرم در حال ارسال
  • یک ویدیو در حال پخش، یا توقف موقت، یا در حال اتمام است.
  • خطایی رخ می دهد.

شما می توانید از این (و از نگاهی اجمالی به مرجع رویداد MDN) که وجود دارد جمع آوری کنید زیادرویدادهایی که می توان به آنها پاسخ داد.

هر رویداد موجود دارای یک کنترل کننده رویداد، که یک بلوک از کد است (معمولاً یک تابع جاوا اسکریپت که شما به عنوان یک برنامه نویس ایجاد می کنید) که هنگام اجرا شدن رویداد اجرا می شود. وقتی چنین بلوکی از کد تعریف می شود که در پاسخ به یک رویداد اجرا شود، می گوییم ما هستیم ثبت یک کنترل کننده رویداد. توجه داشته باشید که کنترل کننده رویداد گاهی اوقات فراخوانی می شود شنوندگان رویداد- آنها تقریباً برای اهداف ما قابل تعویض هستند، اگرچه به طور دقیق، آنها با هم کار می کنند. شنونده به رویدادی که رخ می دهد گوش می دهد و کنترل کننده کدی است که در پاسخ به وقوع آن اجرا می شود.

توجه داشته باشید: رویدادهای وب بخشی از زبان اصلی جاوا اسکریپت نیستند - آنها به عنوان بخشی از APIهای ساخته شده در مرورگر تعریف می شوند.

یک مثال ساده

بیایید به یک مثال ساده نگاه کنیم تا منظورمان را در اینجا توضیح دهیم. شما قبلاً شاهد استفاده از رویدادها و مدیریت رویدادها در بسیاری از مثال‌های این دوره بودید، اما اجازه دهید فقط برای تقویت دانش خود خلاصه کنیم. در مثال زیر. ، یک تک داریم که با فشار دادن آن، پس زمینه به رنگ تصادفی تغییر می کند:

دکمه (حاشیه: 10 پیکسل)؛

جاوا اسکریپت به این صورت است:

Const btn = document.querySelector("button"); تابع تصادفی(عدد) ( بازگشت Math.floor(Math.random() * (شماره+1))؛ ) btn.onclick = function() (const rndCol = "rgb(" + تصادفی(255) + "," + تصادفی(255) + "" + تصادفی(255) + ")"؛ document.body.style.backgroundColor = rndCol؛ )

در این کد، با استفاده از تابع Document.querySelector () یک مرجع به دکمه را در داخل ثابتی به نام btn ذخیره می کنیم. ما همچنین تابعی را تعریف می کنیم که یک عدد تصادفی را برمی گرداند. بخش سوم کد، کنترل کننده رویداد است. ثابت btn به a اشاره می کند تابع bgChange() (const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"؛ document.body.style.backgroundColor = rndCol; )

اولین روش ثبت نام کنترل کننده رویداد که در وب یافت می شود ویژگی های HTML کنترل کننده رویداد(یا کنترل کننده رویداد درون خطی) مانند آنچه در بالا نشان داده شده است - مقدار مشخصه به معنای واقعی کلمه کد جاوا اسکریپتی است که می خواهید هنگام وقوع رویداد اجرا کنید. مثال بالا یک تابع تعریف شده در یک عنصر را فراخوانی می کند که برای جاسازی یا ارجاع کد اجرایی استفاده می شود. این معمولاً برای جاسازی یا ارجاع به کد جاوا اسکریپت استفاده می شود.">

اکثر کنترل‌کننده‌های رویدادی که با آن‌ها مواجه خواهید شد، فقط مجموعه‌ای استاندارد از ویژگی‌ها و توابع (روش‌ها) روی شی رویداد در دسترس دارند؛ برای فهرست کامل به مرجع شی رویداد مراجعه کنید. با این حال، برخی از کنترل‌کننده‌های پیشرفته‌تر، ویژگی‌های تخصصی حاوی داده‌های اضافی را اضافه می‌کنند. به عنوان مثال، Media Recorder API دارای یک رویداد داده در دسترس است، که زمانی فعال می شود که صدا یا ویدیو ضبط شده باشد و برای انجام کاری با آن (مثلاً ذخیره آن، یا پخش آن) در دسترس است. دارای ویژگی داده ای است که حاوی داده های صوتی یا تصویری ضبط شده است تا به شما امکان دسترسی به آن و انجام کاری با آن را بدهد.

جلوگیری از رفتار پیش فرض

گاهی اوقات، با موقعیتی روبرو می شوید که می خواهید از انجام کاری که یک رویداد به طور پیش فرض انجام می دهد جلوگیری کنید. رایج ترین مثال، فرم وب است، به عنوان مثال، یک فرم ثبت نام سفارشی. هنگامی که جزئیات را پر می کنید و دکمه ارسال را فشار دهید، رفتار طبیعی این است که داده ها برای پردازش به یک صفحه مشخص در سرور ارسال شوند، و مرورگر به یک صفحه "پیام موفقیت" هدایت شود (یا همان صفحه، اگر صفحه دیگری باشد. مشخص نشده است.)

مشکل زمانی پیش می‌آید که کاربر داده‌ها را به درستی ارسال نکرده است - به عنوان یک توسعه‌دهنده، می‌خواهید از ارسال به سرور جلوگیری کنید و یک پیغام خطایی بدهید که می‌گوید چه چیزی اشتباه است و چه کاری باید انجام شود تا همه چیز درست شود. برخی از مرورگرها پشتیبانی می‌کنند. ویژگی‌های اعتبارسنجی داده‌های فرم خودکار، اما از آنجایی که بسیاری این کار را نمی‌کنند، به شما توصیه می‌شود به آن‌ها اعتماد نکنید و بررسی‌های اعتبارسنجی خود را اجرا کنید. بیایید به یک مثال ساده نگاه کنیم.

ابتدا یک فرم ساده HTML که از شما می خواهد نام و نام خانوادگی خود را وارد کنید:

Div (حاشیه-پایین: 10 پیکسل؛ )

اکنون مقداری جاوا اسکریپت - در اینجا ما یک بررسی بسیار ساده را در یک کنترل کننده رویداد onsubmit پیاده سازی می کنیم (رویداد ارسال هنگام ارسال روی یک فرم فعال می شود) که خالی بودن فیلدهای متن را آزمایش می کند. در صورت وجود، ما تابع ()preventDefault را روی شی رویداد فراخوانی می کنیم - که ارسال فرم را متوقف می کند - و سپس یک پیام خطا در پاراگراف زیر فرم خود نمایش می دهیم تا به کاربر بگوییم مشکل چیست:

Const form = document.querySelector("form"); const fname = document.getElementById("fname"); const lname = document.getElementById("lname"); const para = document.querySelector("p"); form.onsubmit = function(e) ( if (fname.value === "" || lname.value === "") (e.preventDefault(); para.textContent = "شما باید هر دو نام را پر کنید! ";))

بدیهی است که این یک اعتبار سنجی فرم بسیار ضعیف است - به عنوان مثال، کاربر را از اعتبار سنجی فرم با فاصله ها یا اعداد وارد شده در فیلدها جلوگیری نمی کند - اما برای اهداف مثال خوب است. خروجی به شرح زیر است:

حباب رویداد و ضبط

موضوع آخری که در اینجا باید به آن پرداخته شود، چیزی است که اغلب با آن مواجه نخواهید شد، اما اگر آن را درک نکنید، ممکن است دردسرساز شود. حباب کردن و ضبط رویداد دو مکانیسمی هستند که توصیف می کنند وقتی دو کنترل کننده از یک نوع رویداد روی یک عنصر فعال می شوند چه اتفاقی می افتد. بیایید به یک مثال نگاه کنیم تا این کار آسان‌تر شود - مثال show-video-box.html را در یک برگه جدید باز کنید (و در یک برگه دیگر.) همچنین به صورت زنده در زیر موجود است:

نمونه ویدیوی مخفی
نمایش نمونه جعبه ویدیویی

این یک مثال بسیار ساده است که نشان می دهد و پنهان می کند ) ظرف عمومی برای محتوای جریان است. تا زمانی که با استفاده از CSS استایل داده نشود، تأثیری بر محتوا یا طرح‌بندی ندارد.">

با a) یک پخش کننده رسانه را که از پخش ویدیو در سند پشتیبانی می کند، جاسازی می کند. شما می توانید استفاده کنید