شیء رویداد
روی دیوار موزه یک پلاک است. قاب دورش #wall است. خود پلاک #plaque است و داخلش یک لینک نشسته: #seal. روی لینک نوشته open و نشانیاش /wing است. زیر قاب، بند #slip هنوز blank میگوید.
مرورگر با اجرای تابع یک شیء به آن میدهد. پارامتر را event صدا میزنیم. event.type نوع رویداد است. برای کلیک، این رشته click است. event.target همان عنصری است که کلیک رویش نشسته. event.currentTarget عنصری است که این شنونده روی آن ثبت شده. این دو فقط وقتی یکیاند که کلیک و شنونده روی یک عنصر باشند.
مُهر لینک است. preventDefault نمیگذارد صفحه برود سراغ /wing. بعد از این فراخوانی، event.defaultPrevented برابر true است. اگر صدا نزنی، پرچم false میماند. کلیک بعد از مُهر بیرون میآید: اول پلاک، بعد دیوار. stopPropagation روی پلاک این مسیر را میبُرد. شنوندهٔ دیوار دیگر اجرا نمیشود.
اسکریپت صفحه یک بار روی مُهر کلیک میزند. خط زیر پلاک این است: click / seal / plaque / true / quiet. اینجا onclick نمینویسیم، removeEventListener صدا نمیزنیم، و عنصر تازه هم نمیسازیم.
شیئی که مرورگر میدهد
صفحهٔ قبل چوبلباسی بود. آنجا wool و silk پارامتری نمیگرفتند و این شیء را نمیخواندند. خطشان wool silk / 2 / peg بود. صفحهٔ زنگ، onclick را پر میکرد و this را میخواند. اینجا نه. getElementById فقط قاب، پلاک، مُهر و بند را به دستت میدهد.
addEventListener هنوز فقط تابع را نگه میدارد. شیء وقتی میرسد که کلیک تابع را اجرا کند، نه لحظهٔ اضافه کردن. currentTarget را داخل خود تابع بخوان. تابع که برگردد، این ویژگی null است.
یک کلیک چه میگوید
بند از blank شروع میشود. نوشتهٔ لینک همان open میماند. ردیفها را به ترتیب بخوان. هر قطعه از قاب تازه شروع میشود، جز ردیف صفحه که مال نمایش پایین است. آن نمایش کسی را با removeEventListener برنمیدارد.
📊 یک کلیک چه میگوید
| لحظه | چه را میخوانی | متن بند | لغزش رایج |
|---|---|---|---|
شنونده روی مُهر، seal.click()، خواندن نوع |
event.type |
click | گرفتن شناسه بهجای نوع |
| شنونده روی پلاک، کلیک روی مُهر، خواندن target | event.target.id |
seal | خواندن currentTarget |
| همان کلیک، خواندن currentTarget | event.currentTarget.id |
plaque | خواندن target |
preventDefault روی مُهر، بعد پرچم |
event.defaultPrevented |
true | خیال اینکه لینک هنوز میرود |
بدون preventDefault |
event.defaultPrevented |
false | خیال اینکه هر شنونده لینک را لغو میکند |
stopPropagation روی پلاک، دیوار هم گوش میدهد |
بههمچسبیدن marks | plaque | انتظار plaque wall |
اسکریپت صفحه، یک click |
خط | click / seal / plaque / true / quiet | تمام شدن خط با wall |
کلیک روی مُهر یک شیء است و همهٔ شنوندههای سر راه همان را میبینند. type عوض نمیشود. target هم عوض نمیشود. currentTarget عوض میشود: مال همان عنصری است که شنوندهاش همین حالا در حال اجراست.
preventDefault با کار پیشفرض مرورگر حرف میزند. برای این لینک، آن کار رفتن به /wing است. این فراخوانی شنونده را از فهرست برنمیدارد. stopPropagation با مسیر حرف میزند. لینک را لغو نمیکند. یکی را که صدا بزنی، دیگری صدا زده نشده.
join(" ") فقط بین واژههایی که الان در marks هستند فاصله میگذارد. فهرست خالی را اینجا به هم نمیچسبانیم. بند از واژهٔ blank شروع میشود و فقط داخل شنونده، یا در اسکریپت صفحه بعد از کلیک، عوض میشود.
نوع
شنونده روی خود مُهر است. تابع پارامتر event دارد و event.type را در بند مینویسد. بعد seal.click() اجرا میشود.
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readType(event) {
slip.textContent = event.type;
}
seal.addEventListener("click", readType);
seal.click();
console.log(slip.textContent);
خروجی click است. نوع، جنس رویداد است، نه شناسه و نه واژهٔ open.
عنصری که کلیک رویش نشسته
قاب تازه. شنونده روی پلاک است، نه روی مُهر. کلیک باز روی مُهر مینشیند. event.target همان عنصر است، پس event.target.id برابر seal است.
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readTarget(event) {
slip.textContent = event.target.id;
}
plaque.addEventListener("click", readTarget);
seal.click();
console.log(slip.textContent);
خروجی seal است. عنصر شنونده پلاک است. target پلاک را گزارش نمیکند. عنصری را میگوید که زیر کلیک بوده.
جایی که شنونده نشسته
باز قاب تازه. شنونده هنوز روی پلاک است و کلیک هنوز روی مُهر. بند هر دو شناسه را مینویسد: اول target، بعد currentTarget.
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function readWhere(event) {
slip.textContent = event.target.id + " " + event.currentTarget.id;
}
plaque.addEventListener("click", readWhere);
seal.click();
console.log(slip.textContent);
خروجی seal plaque است. واژهٔ اول مال کلیک است. واژهٔ دوم مال عنصری است که این شنونده روی آن است. اگر همین شنونده را روی خود مُهر بگذاری و روی مُهر کلیک کنی، هر دو شناسه seal میشوند، چون کلیک و شنونده یک عنصر دارند. این خواندن از پلاک است، پس دو شناسه فرق دارند. currentTarget را داخل تابع بخوان. تابع که تمام شود، null است.
لغو لینک
href مُهر /wing است. کار پیشفرض مرورگر برای این کلیک، دنبال کردن لینک است. preventDefault همان کار را لغو میکند. شنونده را برنمیدارد. درست بعد از فراخوانی، event.defaultPrevented برابر true است.
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
function hold(event) {
event.preventDefault();
slip.textContent = String(event.defaultPrevented);
}
seal.addEventListener("click", hold);
seal.click();
console.log(slip.textContent);
خروجی true است. preventDefault را برنداری، همان خواندن false میشود. بند false میگوید و کار پیشفرض لینک سر جایش میماند. stopPropagation این پرچم را true نمیکند.
کلیک به سمت بیرون میرود
مُهر داخل پلاک است و پلاک داخل دیوار. کلیک روی مُهر اول به شنوندهٔ پلاک میرسد، بعد به شنوندهٔ دیوار، مگر مسیر بریده شود. stopPropagation روی پلاک مسیر را میبُرد. تابع دیوار اجرا نمیشود. preventDefault مسیر را نمیبُرد.
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let marks = [];
function onPlaque(event) {
marks.push("plaque");
event.stopPropagation();
}
function onWall() {
marks.push("wall");
}
plaque.addEventListener("click", onPlaque);
wall.addEventListener("click", onWall);
seal.click();
slip.textContent = marks.join(" ");
console.log(slip.textContent);
خروجی plaque است. واژهٔ wall به marks نمیچسبد. بدون stopPropagation همین کلیک plaque wall مینوشت. نمایش پایین هم مسیر را میبُرد و هم لینک را لغو میکند.
یک خط زیر پلاک
اسکریپت ته body است، بعد از اینکه قاب و بندها در صفحه هستند. شنوندهٔ مُهر preventDefault را صدا میزند. شنوندهٔ پلاک stopPropagation را صدا میزند و نوع، شناسهٔ target، شناسهٔ currentTarget و پرچم را نگه میدارد. شنوندهٔ دیوار heard را wall میکرد، ولی مسیر قبلاً بریده شده، پس heard همان quiet میماند. خط بعد از seal.click() نوشته میشود، وقتی دیوار فرصت خودش را داشته.
<!DOCTYPE html>
<html>
<head>
<title>event-object — page</title>
</head>
<body>
<div id="wall">
<div id="plaque">
<a id="seal" href="/wing">open</a>
</div>
</div>
<p id="slip">blank</p>
<p id="line">…</p>
<script>
let wall = document.getElementById("wall");
let plaque = document.getElementById("plaque");
let seal = document.getElementById("seal");
let slip = document.getElementById("slip");
let kind = "";
let from = "";
let on = "";
let held = "";
let heard = "quiet";
seal.addEventListener("click", function (event) {
event.preventDefault();
});
plaque.addEventListener("click", function (event) {
event.stopPropagation();
kind = event.type;
from = event.target.id;
on = event.currentTarget.id;
held = String(event.defaultPrevented);
});
wall.addEventListener("click", function () {
heard = "wall";
});
seal.click();
slip.textContent = kind + " " + from + " " + on;
document.getElementById("line").textContent =
kind + " / " + from + " / " + on + " / " + held + " / " + heard;
</script>
</body>
</html>
خط میشود click / seal / plaque / true / quiet. نوع click است. شناسهٔ target برابر seal است. شناسهٔ currentTarget برابر plaque است، چون آن شنونده روی پلاک نشسته. پرچم true است، چون شنوندهٔ مُهر preventDefault را زودتر صدا زده. واژهٔ آخر quiet است، نه wall، چون stopPropagation روی پلاک اجرا شده. نوشتهٔ open داخل خط نیست. بند میشود click seal plaque. صفحهٔ بعد واگذاری رویداد است. مُهر از اول در نشانهگذاری است. اینجا بعد از شنونده فرزند تازه اضافه نمیکنیم.
پنج وارسی پای پلاک
- شنونده را روی مُهر بگذار و کلیک کن. بند click است.
- شنونده را روی پلاک بگذار، روی مُهر کلیک کن، و
event.target.idرا بخوان. بند seal است. - همان شنونده هر دو شناسه را بنویسد. بند seal plaque است. شنوندهای که روی خود مُهر باشد seal seal مینویسد.
preventDefaultرا صدا بزن وevent.defaultPreventedرا بخوان. بند true است. صدا نزنی، بند false است.- روی پلاک
stopPropagationرا صدا بزن و دیوار هم گوش بدهد. marks به plaque میچسبد. خط صفحه را بخوان: click / seal / plaque / true / quiet.
کجای این پلاک گول میزند
روی لینک هنوز open است. بند، متن لینک نیست.
- انتظار اینکه آرگومان تابع خود عنصر مُهر باشد، نه شیء رویداد
- خواندن
event.targetوقتی عنصر شنونده را میخواستی - خواندن
event.currentTargetوقتی عنصر زیر کلیک را میخواستی - انتظار اینکه
preventDefaultشنونده را بردارد، همان کاری کهremoveEventListenerروی چوبلباسی میکرد - انتظار اینکه
stopPropagationرفتن به/wingرا لغو کند - انتظار اینکه شنوندهٔ دیوار بعد از
stopPropagationروی پلاک هنوز اجرا شود - خواندن
event.currentTargetبعد از برگشتن تابع، و انتظار plaque - نوشتن
onclickیا خواندنthisوtypeof null؛ آن مال صفحهٔ زنگ بود - ساختن لینک با
createElement؛ آن مال صفحهٔ قبلیتر بود - خواندن خط طوری که با wall تمام شود، یا به شکل wool silk / 2 / peg
چه چیز میماند
- بعد از کلیک،
event.typeبرابر click است - شنونده روی پلاک و کلیک روی مُهر:
event.target.idبرابر seal است - همان کلیک:
event.currentTarget.idبرابر plaque است - شنونده روی خود مُهر: target و currentTarget هر دو seal هستند
preventDefaultمقدارevent.defaultPreventedرا true میکند، و بدون آن false میماندstopPropagationروی پلاک نمیگذارد شنوندهٔ دیوار اجرا شود- خط صفحه میشود click / seal / plaque / true / quiet
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود