برنامه نویسی, جاوااسکریپت, فرانت اند

event در جاوا اسکریپت

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

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

پیش نیازها: سواد اولیه کامپیوتر، درک اولیه از HTML و CSS، اولین مراحل جاوا اسکریپت.

هدف: درک نظریه بنیادی event ، نحوه عملکرد آنها در مرورگرها و اینکه چگونه event ممکن است در محیط های برنامه نویسی مختلف متفاوت باشند.

event در جوا اسکریپت چیست؟

event چیزهایی هستند که در سیستمی که در حال برنامه‌نویسی آن هستید رخ می‌دهند. سیستم زمانی که یک event رخ می‌دهد نوعی سیگنال تولید می‌کند (یا “fires” می‌کند) و مکانیزمی را فراهم می‌کند که بوسیله آن می‌توان یک عمل را به طور خودکار انجام داد (یعنی مقداری کد در حال اجرا است. ) ، هنگامی که event رخ می دهد. event در داخل پنجره مرورگر فعال می شوند و تمایل دارند به آیتم خاصی که در آن قرار دارد متصل شوند. این ممکن است یک عنصر، مجموعه ای از عناصر، HTML document بارگیری شده در برگه فعلی یا کل پنجره مرورگر باشد. انواع مختلفی از event وجود دارد که ممکن است رخ دهد.به عنوان مثال:

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

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

توجه: کنترل‌کننده‌های event گاهی شنونده event نامیده می‌شوند،آنها تقریباً برای اهداف ما قابل تعویض هستند، اگرچه به طور دقیق، آنها با هم کار می‌کنند. شنونده به event که رخ می دهد گوش می دهد و کنترل کننده کدی است که در پاسخ به وقوع آن اجرا می شود.

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

یک مثال: مدیریت یک event کلیک

در مثال زیر، یک <button> در صفحه داریم:

<button>Change color</button>

سپس مقداری جاوا اسکریپت داریم. در بخش بعدی به این موضوع با جزئیات بیشتری نگاه خواهیم کرد، اما در حال حاضر فقط می توانیم بگوییم: یک کنترل کننده event را به event “click” دکمه اضافه می کند و کنترل کننده با تنظیم پس زمینه صفحه به صورت رنگ تصادفی به رویداد واکنش نشان می دهد:

const btn = document.querySelector(“button”);

function random(number) {

  return Math.floor(Math.random() * (number + ۱));

}

btn.addEventListener(“click”, () => {

  const rndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

  document.body.style.backgroundColor = rndCol;

});

خروجی نمونه به صورت زیر است. سعی کنید روی دکمه کلیک کنید(در سیستم خودتان):


استفاده از ()addEventListener

همانطور که در مثال آخر دیدیم، اشیایی که می‌توانند event ها را اجرا کنند دارای یک متد ()adEventListener هستند و این مکانیزم توصیه‌شده برای اضافه کردن کنترل‌کننده event است.

بیایید نگاهی دقیق تر به کد نمونه آخر بیندازیم:

const btn = document.querySelector(“button”);

function random(number) {

  returnMath.floor(Math.random() * (number + ۱));

}

btn.addEventListener(“click”, () => {

  const rndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

 document.body.style.backgroundColor = rndCol;

});

عنصر <HTML <button یک event را هنگامی که کاربر روی دکمه کلیک می‌کند فعال می‌کند. بنابراین یک تابع ()addEventListener تعریف می کند که ما در اینجا آن را فراخوانی می کنیم. ما در دو پارامتر عبور می کنیم:

1.رشته “click” را نشان می دهد که نشان می دهد می خواهیم به event کلیک گوش دهیم. دکمه‌ها می‌توانند بسیاری از event دیگر را اجرا کنند، مانند “Moeover” زمانی که کاربر ماوس خود را روی دکمه حرکت می‌دهد، یا “keydown” زمانی که کاربر کلیدی را فشار می‌دهد و دکمه فوکوس می‌شود.

2.یک تابع برای فراخوانی در هنگام وقوع event . در مورد ما، تابع یک رنگ RGB تصادفی تولید می کند و رنگ پس زمینه <body> صفحه را روی آن رنگ تنظیم می کند.

خوب است که تابع handler را یک تابع با نام جداگانه قرار دهید، مانند این:

const btn = document.querySelector(“button”);

function random(number) {

  return Math.floor(Math.random()* (number + ۱));

}

function changeBackground() {

  const rndCol =`rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

  document.body.style.backgroundColor = rndCol;

}

btn.addEventListener(“click”changeBackground);

گوش دادن به event های دیگر

بسیاری از event های مختلف وجود دارد که می تواند توسط یک عنصر دکمه شلیک شود. بیایید آزمایش کنیم.

ابتدا یک نسخه محلی از رنگ تصادفی-addeventlistener.html تهیه کنید و آن را در مرورگر خود باز کنید. این فقط یک نسخه از مثال ساده رنگ تصادفی است که قبلاً با آن بازی کرده ایم. اکنون سعی کنید به نوبه خود به مقادیر مختلف زیر کلیک کنید و نتایج را در مثال مشاهده کنید:

Focus and Blure – رنگ هنگامی که دکمه متمرکز و نامتمرکز است تغییر می کند. سعی کنید روی tab فشار دهید تا روی دکمه تمرکز کنید و دوباره tab را فشار دهید تا به دور از دکمه تمرکز کنید. این موارد اغلب برای نمایش اطلاعات در مورد پر کردن قسمت های فرم هنگام تمرکز یا نمایش پیام خطا در صورت پر کردن یک قسمت فرم با یک مقدار نادرست استفاده می شود.

DBLCLICK- رنگ فقط هنگامی که بر روی دکمه دو بار کلیک می شود تغییر می کند.

mouseover and mouseout – رنگ هنگامی که نشانگر ماوس روی دکمه حرکت می کند ، یا هنگامی که نشانگر از دکمه خارج می شود ، تغییر می کند.

برخی از event ، مانند کلیک ، تقریباً در هر عنصر موجود است. برخی دیگر در موقعیت های خاص خاص تر و فقط مفید هستند: به عنوان مثال ، event play فقط در برخی از عناصر مانند <video> در دسترس است.

حذف شنوندگان

اگر یک کنترل کننده event را با استفاده از ()addeventlistener اضافه کرده اید ، می توانید دوباره با استفاده از روش ()removeventlistener دوباره آن را حذف کنید. به عنوان مثال ، این کار کنترل کننده event ()Changebackground را حذف می کند:

btn.removeEventListener(“click”changeBackground);

کنترل‌کننده‌های event را می‌توان با ارسال یک AbortSignal به ()addEventListener و سپس فراخوانی ()abort روی کنترل‌کننده‌ای که دارای AbortSignal است حذف کرد. به عنوان مثال، برای اضافه کردن یک کنترل کننده event که می توانیم با AbortSignal حذف کنیم:

const controller =new AbortController();

btn.addEventListener(

  “click”,

  ()=> {

    const rndCol = `rgb(${random(۲۵۵)},${random(۲۵۵)}, ${random(۲۵۵)})`;

    document.body.style.backgroundColor = rndCol;

  },

  { signal: controller.signal }

); // pass an AbortSignal to this handler

سپس کنترل کننده event ایجاد شده توسط کد بالا را می توان به صورت زیر حذف کرد:

controller.abort();// removes any/all event handlers associated with this controller

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

افزودن چندین شنونده برای یک event واحد

با برقراری بیش از یک تماس با ()addEventListener ، ارائه کنترلرهای مختلف، می توانید چندین کنترل کننده برای یک event واحد داشته باشید:

myElement.addEventListener(“click”functionA);

myElement.addEventListener(“click”functionB);

هر دو تابع اکنون با کلیک روی عنصر اجرا می شوند.

بیشتر بدانید

ویژگی ها و گزینه های قدرتمند دیگری با ()addEventListener در دسترس هستند.

اینها کمی خارج از محدوده این مقاله هستند، اما اگر می خواهید آنها را بخوانید، از صفحات مرجع ()addEventListener و ()removeEventListener دیدن کنید.

سایر مکانیسم های شنونده event

توصیه می کنیم از ()addEventListener برای ثبت کنترل کننده event استفاده کنید. این قوی‌ترین روش است و با برنامه‌های پیچیده‌تر، بهترین مقیاس را دارد. با این حال، دو راه دیگر برای ثبت کنترل کننده event وجود دارد که ممکن است مشاهده کنید: ویژگی های کنترل کننده event و کنترل کننده event درون خطی.

ویژگی های کنترل کننده event

اشیاء (مانند دکمه‌ها) که می‌توانند event ها را فعال کنند نیز معمولاً دارای ویژگی‌هایی هستند که نام آن‌ها on و به دنبال آن نام event است. به عنوان مثال، عناصر دارای یک ویژگی onclick هستند. به این ویژگی مدیریت event می گویند. برای گوش دادن به event ، می توانید تابع handler را به ویژگی اختصاص دهید.

برای مثال، می‌توانیم مثال رنگ تصادفی را به این صورت بازنویسی کنیم:

const btn = document.querySelector(“button”);

functionrandom(number) {

  return Math.floor(Math.random() * (number + ۱));

}

btn.onclick = () => {

  const rndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

  document.body.style.backgroundColor = rndCol;

};

همچنین می توانید ویژگی handler را روی یک تابع با نام تنظیم کنید:

const btn = document.querySelector(“button”);

function random(number) {

  return Math.floor(Math.random() * (number + ۱));

}

function bgChange() {

  const rndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

  document.body.style.backgroundColor = rndCol;

}

btn.onclick = bgChange;

با ویژگی های کنترل کننده event ، نمی توانید بیش از یک کنترل کننده برای یک event اضافه کنید. برای مثال، می‌توانید addEventListener(‘click’, handler) را چندین بار روی یک عنصر فراخوانی کنید، با توابع مختلف مشخص شده در آرگومان دوم:

element.addEventListener(“click”function1);

element.addEventListener(“click”function2);

این با ویژگی های event کنترل کننده غیرممکن است زیرا هر تلاش بعدی برای تنظیم ویژگی، موارد قبلی را بازنویسی می کند:

element.onclick = function1;

element.onclick = function2;

کنترل کننده event های درون خطی (*از آنها استفاده نکنید*)

همچنین ممکن است الگویی مانند این را در کد خود مشاهده کنید:

اولین روش ثبت کنترل کننده event که در وب یافت می شود شامل ویژگی های HTML کنترل کننده event (یا کنترل کننده event درون خطی) مانند آنچه در بالا نشان داده شده است – مقدار مشخصه به معنای واقعی کلمه کد جاوا اسکریپتی است که می خواهید هنگام وقوع event اجرا کنید. مثال بالا تابعی را فراخوانی می کند که در داخل یک عنصر <script> در همان صفحه تعریف شده است، اما شما همچنین می توانید جاوا اسکریپت را مستقیماً در داخل ویژگی وارد کنید، به عنوان مثال:

<buttononclick=”alert(‘Hello, this is my old-fashioned event handler!’);”>
  Press me

</button>

می‌توانید معادل‌های ویژگی HTML را برای بسیاری از ویژگی‌های مدیریت event پیدا کنید. با این حال، شما نباید از اینها استفاده کنید – آنها عمل بدی در نظر گرفته می شوند. اگر کاری واقعاً سریع انجام می دهید، ممکن است استفاده از ویژگی مدیریت event آسان به نظر برسد، اما آنها به سرعت غیرقابل مدیریت و ناکارآمد می شوند.

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

حتی در یک فایل واحد، مدیریت event های درون خطی ایده خوبی نیستند. یک دکمه اوکی است، اما اگر ۱۰۰ دکمه داشته باشید چه؟ شما باید ۱۰۰ ویژگی به فایل اضافه کنید. به سرعت به یک کابوس تعمیر و نگهداری تبدیل می شود. با جاوا اسکریپت، می‌توانید به راحتی یک تابع مدیریت event را به همه دکمه‌های صفحه بدون توجه به تعداد زیاد، با استفاده از چیزی شبیه به این اضافه کنید:

const buttons = document.querySelectorAll(“button”);
for (const button of buttons) {
button.addEventListener(“click”bgChange);
}

در نهایت، بسیاری از پیکربندی های رایج سرور، جاوا اسکریپت درون خطی را به عنوان یک اقدام امنیتی ممنوع می کنند.شما هرگز نباید از ویژگی های کنترل کننده event HTML استفاده کنید – این ویژگی ها قدیمی هستند و استفاده از آنها عمل بدی است.

اشیاء event (event objects)

گاهی اوقات، در داخل یک تابع کنترل کننده event ، پارامتری را می بینید که با نامی مانند event، evt یا e مشخص شده است. این شیء event نامیده می شود و به طور خودکار به کنترل کننده event ارسال می شود تا ویژگی ها و اطلاعات اضافی را ارائه دهد. به عنوان مثال، اجازه دهید مثال رنگ تصادفی خود را دوباره کمی بازنویسی کنیم:

const btn = document.querySelector(“button”);

function random(number) {

  return Math.floor(Math.random() * (number + ۱));

}

function bgChange(e) {

  const rndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)}, ${random(۲۵۵)})`;

  e.target.style.backgroundColor = rndCol;

  console.log(e);

}

btn.addEventListener(“click”bgChange);

در اینجا می‌توانید ببینید که ما یک شی event ، e، را در تابع، و در تابعی که یک سبک رنگ پس‌زمینه را در e.target تنظیم می‌کنیم – که خود دکمه است، اضافه می‌کنیم. ویژگی هدف شی event همیشه ارجاع به عنصری است که event روی آن رخ داده است. بنابراین، در این مثال، ما یک رنگ پس زمینه تصادفی را روی دکمه تنظیم می کنیم، نه صفحه.

توجه: می‌توانید از هر نامی که دوست دارید برای شی event استفاده کنید – فقط باید نامی را انتخاب کنید که می‌توانید برای ارجاع آن در تابع کنترل event استفاده کنید. e/evt/event بیشتر توسط توسعه دهندگان استفاده می شود زیرا کوتاه هستند و به راحتی قابل یادآوری هستند. همیشه خوب است که سازگار باشید – با خودتان و در صورت امکان با دیگران.

ویژگی های اضافی اشیاء event

اکثر اشیاء event دارای مجموعه ای استاندارد از ویژگی ها و روش های موجود در شی event هستند.

برخی از اشیاء event ویژگی‌های اضافی را اضافه می‌کنند که مربوط به آن نوع خاص از event است. برای مثال، زمانی که کاربر کلیدی را فشار می‌دهد، event keydown فعال می‌شود. شی event آن یک KeyboardEvent است که یک شی event تخصصی با ویژگی کلیدی است که به شما می گوید کدام کلید فشرده شده است:

<input id=”textBox” type=”text” />
<div id=”output“></div>

const textBox = document.querySelector(“#textBox”);
const output = document.querySelector(“#output”);
textBox.addEventListener(
“keydown”,
(event=> (output.textContent = `You pressed “${event.key}“.`)
);

برنامه را اجرا کنید با تصویر زیر مواجه میشوید ؛ سعی کنید در کادر متن تایپ کنید و خروجی را ببینید:

پیشگیری از رفتار پیش فرض

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

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

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

<form>
<div>
<label for=”fname“>First name: </label>
<input id=”fname” type=”text” />
</div>
<div>
<label for=”lname“>Last name: </label>
<input id=”lname” type=”text” />
</div>
<div>
<input id=”submit” type=”submit” />
</div>
</form>
<p></p>

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

const form = document.querySelector(“form”);
const fname = document.getElementById(“fname”);
const lname = document.getElementById(“lname”);
const para = document.querySelector(“p”);

form.addEventListener(“submit”, (e=> {
if (fname.value === “” || lname.value === “”) {
e.preventDefault();
para.textContent = “You need to fill in both names!”;
}
});

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

حباب رویداد(event bubbling)

حباب event توضیح می‌دهد که مرورگر چگونه event هایی را که در عناصر تودرتو هدف قرار می‌گیرند مدیریت می‌کند.

تنظیم شنونده بر روی عنصر والد

یک صفحه وب مانند این را در نظر بگیرید:

<div id=”container“>
<button>Click me!</button>
</div>
<pre id=”output“></pre>

در اینجا دکمه داخل عنصر دیگری است، یعنی عنصر <div> . ما می گوییم که عنصر <div> در اینجا والد عنصری است که شامل آن است. اگر یک کنترل کننده event کلیک را به والد اضافه کنیم، سپس روی دکمه کلیک کنیم، چه اتفاقی می افتد؟

const output = document.querySelector(“#output”);
function handleClick(e) {
output.textContent += `You clicked on a ${e.currentTarget.tagName}elementn`;
}
const container = document.querySelector(“#container”);
container.addEventListener(“click”handleClick);


خواهید دید که وقتی کاربر روی دکمه کلیک می‌کند، والد یک رویداد کلیک را اجرا می‌کند: You clicked on a DIV element

این منطقی است زیرا دکمه در داخل <div> است، بنابراین وقتی روی دکمه کلیک می‌کنید، به طور ضمنی روی عنصری که داخل آن است نیز کلیک می‌کنید.

مثال حباب(Bubbling example)
اگر شنوندگان رویداد را به دکمه و والد اضافه کنیم چه اتفاقی می‌افتد؟

<body>
<div id=”container“>
<button>Click me!</button>
</div>
<pre id=”output“></pre>
</body>

اجازه دهید کنترل‌کننده‌های رویداد کلیک را به دکمه، والد آن (<div>) و عنصر <body> که هر دوی آنها را در بر می‌گیرد اضافه کنیم:

const output = document.querySelector(“#output”);
function handleClick(e) {
output.textContent += `You clicked on a ${e.currentTarget.tagName}elementn`;
}
const container = document.querySelector(“#container”);
const button = document.querySelector(“button”);
document.body.addEventListener(“click”handleClick);
container.addEventListener(“click”handleClick);
button.addEventListener(“click”handleClick);

مشاهده خواهید کرد که هر سه عنصر با کلیک روی دکمه، یک event کلیک را فعال می کنند:
You clicked on a BUTTON element
You clicked on a DIV element
You clicked on a BODY element

در این مورد:

ابتدا روی دکمه کلیک کنید.
سپس روی والد آن کلیک کنید (عنصر<div>)
پس از آن والد عنصر <div> (عنصر <body>) قرار می گیرد.

ما این را با گفتن اینکه event از درونی‌ترین عنصری که روی آن کلیک شده است، bubbles up می‌شود، توضیح می‌دهیم.

این رفتار می تواند مفید باشد و همچنین می تواند باعث ایجاد مشکلات غیرمنتظره شود. در بخش‌های بعدی، مشکلی را که ایجاد می‌کند، خواهیم دید و راه‌حل آن را پیدا می‌کنیم.

مثال Video player

در این مثال صفحه ما حاوی یک ویدیو است که در ابتدا مخفی است و دکمه ای با عنوان “نمایش ویدئو” دارد. ما تعامل زیر را می خواهیم:

وقتی کاربر روی دکمه «Display video» کلیک کرد، کادر حاوی ویدیو را نشان دهید، اما هنوز پخش ویدیو را شروع نکنید.
وقتی کاربر روی ویدیو کلیک کرد، شروع به پخش ویدیو کنید.
وقتی کاربر در جایی از کادر خارج از ویدیو کلیک می کند، کادر را پنهان کنید.

HTML به شکل زیر است:

<button>Display video</button>
<divclass=”hidden“>
<video>
<source
src=”https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm
type=”video/webm” />
<p>
      Your browser doesn’t support HTML video. Here is a
      <a href=”rabbit320.mp4“>link to the video</ainstead.
</p>
</video>
</div>

شامل موارد زیر است:

یک عنصر<button>
یک عنصر<div> که در ابتدا دارای یک ویژگی “class=”hidden است.
یک عنصر <video> که در داخل عنصر<div> قرار دارد.

ما از CSS برای پنهان کردن عناصر با مجموعه کلاس “hidden” استفاده می کنیم.

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

const btn = document.querySelector(“button”);
const box = document.querySelector(“div”);
const video = document.querySelector(“video”);

btn.addEventListener(“click”, () => box.classList.remove(“hidden”));
video.addEventListener(“click”, () => video.play());
box.addEventListener(“click”, () => box.classList.add(“hidden”));

این سه شنونده event «click» را اضافه می‌کند:
یکی در <button> ، که <div> را که حاوی <video> است را نشان میدهد.
یکی در <video> که شروع به پخش ویدیو می کند.
یکی در <div> که ویدئو را پنهان میکند.

بع از اجرای برنامه باید ببینید که وقتی روی دکمه کلیک می‌کنید، کادر و ویدئوی موجود در آن نشان داده می‌شود. اما وقتی روی ویدئو کلیک می‌کنید، ویدیو شروع به پخش می‌کند، اما کادر دوباره پنهان می‌شود! اما چرا؟

چون ویدئو در داخل <div> است (بخشی از آن است) ، بنابراین کلیک کردن روی ویدیو هر دو کنترل کننده event را اجرا می کند و باعث این رفتار می شود.

رفع مشکل ()stopPropagation

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

ما می توانیم با تغییر جاوا اسکریپت به این ، مشکل فعلی خود را برطرف کنیم:

const btn = document.querySelector(“button”);
const box = document.querySelector(“div”);
const video = document.querySelector(“video”);
btn.addEventListener(“click”, () => box.classList.remove(“hidden”));
video.addEventListener(“click”, (event=> {
event.stopPropagation();
video.play();
});
box.addEventListener(“click”, ()=> box.classList.add(“hidden”));

تمام کاری که ما در اینجا انجام می دهیم فراخوانی ()stopPropagation روی شی رویداد در کنترل کننده برای رویداد ‘click’ عنصر <video> است. با این کار از حباب زدن آن رویداد تا جعبه جلوگیری می‌شود.

ضبط رویداد (event capture)

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

ضبط رویداد به طور پیش فرض غیرفعال است. برای فعال کردن آن باید گزینه capture را در ()addEventListener پاس کنید.

این مثال دقیقاً مانند Bubbling example است که قبلاً دیدیم، با این تفاوت که از گزینه capture استفاده کرده‌ایم:

در این مورد، ترتیب پیام‌ها برعکس می‌شود: ابتدا کنترل‌کننده رویداد <body> و سپس کنترل‌کننده رویداد <div> و به‌دنبال کنترل‌کننده رویداد <button> فعال میشود:
You clicked on a BODY element
You clicked on a DIV element
You clicked on a BUTTON element

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

به‌طور پیش‌فرض، تقریباً همه کنترل‌کننده‌های event در مرحله حباب ثبت می‌شوند، و این بیشتر اوقات منطقی‌تر است.

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

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

در اینجا HTML آمده است:

<div id=”container“>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
<div class=”tile“></div>
</div>

ما یک CSS کوچک برای تنظیم اندازه و موقعیت کاشی ها داریم:

.tile {
height: 100px;
width: ۲۵%;
float: left;
}

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

function random(number) {
return Math.floor(Math.random() * number);
}
function bgChange() {
constrndCol = `rgb(${random(۲۵۵)}, ${random(۲۵۵)},${random(۲۵۵)})`;
return rndCol;
}
const container = document.querySelector(“#container”);
container.addEventListener(
“click”,
(event) => (event.target.style.backgroundColor = bgChange())
);

توجه: در این مثال، ما از event.target برای بدست آوردن عنصری که هدف event بود (یعنی درونی ترین عنصر) استفاده می کنیم. اگر بخواهیم به عنصری که این event را مدیریت می‌کند دسترسی داشته باشیم، می‌توانیم از event.currentTarget استفاده کنیم.

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

به عنوان مثال، Node.js یک runtime جاوا اسکریپت بسیار محبوب است که توسعه دهندگان را قادر می سازد از جاوا اسکریپت برای ساختن شبکه و برنامه های سمت سرور استفاده کنند. مدل event Node.js به شنوندگان برای گوش دادن به event و امیترها برای انتشار دوره‌ای رمتکی است – به نظر متفاوت نیست، اما کد کاملاً متفاوت است و از توابعی مانند ()on برای ثبت شنونده event استفاده می‌کند. ()Once برای ثبت شنونده event که پس از یک بار اجرا از ثبت نام خارج می شود. اسناد event اتصال HTTP مثال خوبی را ارائه می دهد.

همچنین می‌توانید از جاوا اسکریپت برای ایجاد افزونه‌های بین مرورگر ، بهبود عملکرد مرورگر ، با استفاده از فناوری به نام WebExtensions استفاده کنید. مدل event شبیه به مدل event های وب است، اما کمی متفاوت است ؛ ویژگی‌های شنوندگان event به صورت camel-cased هستند (مانند onMessage به جای onemessage) و باید با تابع addListener ترکیب شوند.

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

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

همچنین، درک این نکته مهم است که زمینه‌های مختلف که در آن جاوا اسکریپت استفاده می‌شود، مدل‌های event متفاوتی دارند ، از APIهای وب گرفته تا مناطق دیگر مانند WebExtensions مرورگر و Node.js (جاوا اسکریپت سمت سرور). ما از شما انتظار نداریم که همه این زمینه ها را در حال حاضر درک کنید، اما مطمئناً این مقاله به درک اصول اولیه event در هنگام پیشرفت در یادگیری توسعه وب کمک می کند.

اگر چیزی وجود دارد که متوجه نشدید، در صورت تمایل دوباره مقاله را بخوانید یا با ما تماس بگیرید تا کمک بخواهید.ما در کیهان وب همیشه در کنار شما هستیم!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *