در حال بارگذاری...

شیء رویداد

روی دیوار موزه یک پلاک است. قاب دورش #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() اجرا می‌شود.

خواندن نوع

javascript
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 است.

خواندن target

javascript
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.

خواندن هر دو شناسه

javascript
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 است.

لغو لینک

javascript
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 مسیر را نمی‌بُرد.

بریدن مسیر

javascript
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() نوشته می‌شود، وقتی دیوار فرصت خودش را داشته.

نمایش صفحه — پلاک موزه

html
<!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. صفحهٔ بعد واگذاری رویداد است. مُهر از اول در نشانه‌گذاری است. اینجا بعد از شنونده فرزند تازه اضافه نمی‌کنیم.

پنج وارسی پای پلاک

  1. شنونده را روی مُهر بگذار و کلیک کن. بند click است.
  2. شنونده را روی پلاک بگذار، روی مُهر کلیک کن، و event.target.id را بخوان. بند seal است.
  3. همان شنونده هر دو شناسه را بنویسد. بند seal plaque است. شنونده‌ای که روی خود مُهر باشد seal seal می‌نویسد.
  4. preventDefault را صدا بزن و event.defaultPrevented را بخوان. بند true است. صدا نزنی، بند false است.
  5. روی پلاک 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

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
8
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود