,
همان دسته های قبلی وجود دارد، اما این بار - در مرحله غوطه وری. خوب، برای مشاهده عمل رهگیری، روی عنصر موجود در آن کلیک کنید
کنترل کننده ها به ترتیب از بالا به پایین کار خواهند کرد: 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 و سپس روی این li جدید کلیک کنید - عکس العمل نشان نمی دهد:
بند 1
نقطه 2
نقطه 3
نقطه 4
نقطه 5
li را اضافه کنید
برای حل مشکل، در زمان ایجاد یک li جدید، یک تابع را روی آن آویزان کنید addSign از طریق addEventListener. بیایید این را پیاده سازی کنیم:
بند 1
نقطه 2
نقطه 3
نقطه 4
نقطه 5
li را اضافه کنید 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
li را اضافه کنید 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 وجود دارد که روی هر کدام یک کنترلر وجود دارد:
کد:
حباب تضمین می کند که یک کلیک بر روی داخلی
ابتدا با کنترل کننده onclick (در صورت وجود) روی آن تماس می گیرد
بنابراین، اگر در مثال بالا روی P کلیک کنید، هشدار به صورت متوالی نمایش داده می شود: p → div → form.
این فرآیند حباب نامیده می شود زیرا رویدادهایی که از عنصر درونی از طریق والدین به بالا حباب می شوند، بسیار شبیه به شناور شدن حباب هوا در آب است.
رویداد.هدف
با توجه به هر عنصری که رویداد را بگیریم، همیشه میتوانید دقیقاً محل وقوع آن را پیدا کنید. عمیق ترین عنصری که رویداد را فعال می کند عنصر "هدف" یا "منبع" نامیده می شود و به عنوان event.target در دسترس است.
تفاوت با این (=event.currentTarget):
event.target عنصر منبعی است که رویداد روی آن رخ داده است، در طول فرآیند حباب تغییر نمی کند.
این عنصر فعلی است که حباب به آن رسیده است، کنترل کننده در حال حاضر روی آن اجرا می کند.
به عنوان مثال، اگر فقط یک handler form.onclick وجود داشته باشد، تمام کلیکهای داخل فرم را میگیرد. هر جا که یک کلیک در داخل وجود دارد - به عنصر ظاهر می شود
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) یک پخش کننده رسانه را که از پخش ویدیو در سند پشتیبانی می کند، جاسازی می کند. شما می توانید استفاده کنید
برای محتوای صوتی نیز، اما عنصر ممکن است تجربه کاربری مناسب تری را ارائه دهد."> عنصر داخل آن:
نمایش ویدئو
مرورگر شما از ویدیوی HTML5 پشتیبانی نمیکند. در عوض پیوندی به ویدیو وجود دارد.
توجه داشته باشید : چرا هم با گرفتن و هم حباب زدن به خود زحمت بدهیم؟ خوب، در روزگار بد قدیم که مرورگرها نسبت به الان با یکدیگر سازگاری کمتری داشتند، نت اسکیپ فقط از ثبت رویداد استفاده می کرد و اینترنت اکسپلورر فقط از حباب رویداد استفاده می کرد. هنگامی که W3C تصمیم گرفت تا رفتار را استاندارد کند و به یک اجماع دست یابد، به این سیستم رسیدند که هر دو را شامل می شد، که مرورگرهای مدرن پیاده سازی شده است.
توجه داشته باشید : همانطور که در بالا ذکر شد، بهطور پیشفرض همه کنترلکنندههای رویداد در مرحله حبابسازی ثبت میشوند، و این بیشتر اوقات منطقیتر است. اگر واقعاً میخواهید یک رویداد را در مرحله ضبط به جای آن ثبت کنید، میتوانید این کار را با ثبت handler خود با استفاده از addEventListener() انجام دهید و ویژگی سوم اختیاری را روی true تنظیم کنید.
هیئت رویداد
حباب زدن همچنین به ما امکان می دهد از مزایای آن استفاده کنیم هیئت رویداد - این مفهوم بر این واقعیت متکی است که اگر می خواهید زمانی که روی هر یک از تعداد زیادی عنصر فرزند کلیک می کنید، مقداری کد اجرا شود، می توانید شنونده رویداد را روی والد آنها تنظیم کنید و رویدادهایی را که روی آنها اتفاق می افتد به والد خود تبدیل کنید. به جای اینکه مجبور باشید شنونده رویداد را روی هر کودک جداگانه تنظیم کنید. به یاد داشته باشید که قبلاً گفتیم حباب شامل بررسی عنصری است که رویداد روی آن برای کنترل کننده رویداد اجرا می شود، سپس به سمت والد عنصر حرکت می کند و غیره؟
یک مثال خوب، مجموعه ای از آیتم های لیست است - اگر می خواهید هر یک از آنها با کلیک کردن، پیامی ظاهر شود، می توانید شنونده رویداد کلیک را روی والد تنظیم کنید.
و رویدادها از آیتم های لیست به حباب می شوند .
این مفهوم در وبلاگ دیوید والش با مثالهای متعدد توضیح داده شده است - به نحوه عملکرد نمایندگی رویداد جاوا اسکریپت مراجعه کنید.
نتیجه
اکنون باید همه آنچه را که در این مرحله اولیه درباره رویدادهای وب نیاز دارید بدانید. همانطور که در بالا ذکر شد، رویدادها واقعاً بخشی از جاوا اسکریپت اصلی نیستند - آنها در APIهای وب مرورگر تعریف می شوند.