Eventها در جاوااسکریپت
بهنام نوبخت · ۱۴۰۵/۷/۱۱
تا اینجا یاد گرفتیم چگونه با استفاده از DOM عناصر HTML را پیدا کنیم و محتوای آنها، ویژگیها، کلاسها و حتی ساختار صفحه را با جاوااسکریپت تغییر دهیم. اما یک سؤال مهم باقی میماند: چگونه کاری کنیم که جاوااسکریپت در واکنش به رفتار کاربر اجرا شود؟
فرض کنید میخواهیم وقتی کاربر روی یک دکمه کلیک کرد، یک پیام نمایش داده شود. یا وقتی کاربر داخل یک Input چیزی تایپ کرد، مقدار آن را دریافت کنیم. یا وقتی یک فرم ارسال شد، اطلاعات آن را بررسی کنیم.
برای انجام این کار از مفهومی به نام Event استفاده میکنیم.
در این مقاله با مفهوم Event، انواع رویدادهای مهم، روش addEventListener()، رویدادهای Mouse، Keyboard، Input، Form و چندین مثال کاربردی آشنا خواهیم شد.
Event چیست؟
Event یا رویداد، اتفاقی است که در مرورگر رخ میدهد و جاوااسکریپت میتواند به آن واکنش نشان دهد.
برای مثال:
کاربر روی یک دکمه کلیک میکند.
کاربر یک کلید صفحهکلید را فشار میدهد.
کاربر چیزی داخل Input وارد میکند.
مقدار یک Select تغییر میکند.
کاربر فرم را ارسال میکند.
نشانگر Mouse وارد یک عنصر میشود.
نشانگر Mouse از یک عنصر خارج میشود.
صفحه بارگذاری میشود.
همه این اتفاقات میتوانند Event ایجاد کنند.
به صورت ساده:
User Action
↓
Event
↓
جاوااسکریپت
↓
Actionمثلاً:
Click Button
↓
click Event
↓
جاوااسکریپت
↓
Show Messageاولین Event با click
فرض کنید یک دکمه داریم:
<button id="btn">
Click Me
</button>میخواهیم وقتی کاربر روی آن کلیک کرد، یک پیام در Console نمایش داده شود.
ابتدا دکمه را پیدا میکنیم:
const button = document.getElementById("btn");سپس به آن Event اضافه میکنیم.
addEventListener چیست؟
متد:
addEventListener()برای گوش دادن به یک Event استفاده میشود.
مثال:
const button = document.getElementById("btn");
button.addEventListener("click", function () {
console.log("Button clicked!");
});اکنون هر بار کاربر روی دکمه کلیک کند، کد داخل تابع اجرا میشود.
ساختار addEventListener
ساختار کلی:
element.addEventListener("event", function () {
// Code
});مثلاً:
button.addEventListener("click", function () {
console.log("Hello");
});سه بخش اصلی داریم:
element
↓
event
↓
functionیعنی:
کدام عنصر؟
به چه رویدادی گوش بده؟
هنگام رخ دادن رویداد چه کاری انجام بده؟
Event Handler چیست؟
تابعی که هنگام رخ دادن یک Event اجرا میشود، معمولاً Event Handler یا تابع مدیریت رویداد نامیده میشود.
مثلاً:
button.addEventListener("click", function () {
console.log("Clicked");
});تابعی که بعد از کلیک اجرا میشود، Event Handler است.
استفاده از Function جداگانه
لازم نیست حتماً تابع را داخل addEventListener() بنویسیم.
میتوانیم ابتدا تابع را ایجاد کنیم:
function handleClick() {
console.log("Button clicked!");
}سپس:
button.addEventListener("click", handleClick);توجه کنید که اینجا نباید بنویسیم:
button.addEventListener("click", handleClick());چون handleClick() باعث اجرای فوری تابع میشود.
ما باید خود تابع را به عنوان Handler معرفی کنیم:
button.addEventListener("click", handleClick);تغییر محتوای صفحه با Event
Eventها زمانی جذاب میشوند که آنها را با DOM ترکیب کنیم.
HTML:
<h1 id="title">
Hello
</h1>
<button id="btn">
Change Title
</button>جاوااسکریپت:
const title = document.getElementById("title");
const button = document.getElementById("btn");
button.addEventListener("click", function () {
title.textContent = "Hello جاوااسکریپت";
});اکنون با کلیک روی دکمه، متن h1 تغییر میکند.
نمایش پیام
HTML:
<button id="btn">
Show Message
</button>
<p id="message"></p>جاوااسکریپت:
const button = document.getElementById("btn");
const message = document.getElementById("message");
button.addEventListener("click", function () {
message.textContent = "Welcome!";
});رویداد Mouse
مرورگر Eventهای مختلفی مربوط به Mouse دارد.
برخی از مهمترین آنها:
click
dblclick
mousedown
mouseup
mousemove
mouseenter
mouseleave
mouseover
mouseoutدر ادامه مهمترین موارد را بررسی میکنیم.
click
click زمانی اتفاق میافتد که کاربر روی یک عنصر کلیک کند.
button.addEventListener("click", function () {
console.log("Clicked");
});این یکی از پرکاربردترین Eventها در جاوااسکریپت است.
dblclick
dblclick زمانی اجرا میشود که کاربر دوبار سریع روی یک عنصر کلیک کند.
button.addEventListener("dblclick", function () {
console.log("Double clicked");
});mouseenter
زمانی که Mouse وارد محدوده یک عنصر شود:
const box = document.getElementById("box");
box.addEventListener("mouseenter", function () {
console.log("Mouse entered");
});mouseleave
زمانی که Mouse از عنصر خارج شود:
box.addEventListener("mouseleave", function () {
console.log("Mouse left");
});mousemove
زمانی که Mouse روی یک عنصر حرکت کند:
box.addEventListener("mousemove", function () {
console.log("Mouse is moving");
});این Event ممکن است تعداد زیادی بار اجرا شود، بنابراین در عملیات سنگین باید با احتیاط استفاده شود.
Keyboard Eventها
جاوااسکریپت میتواند به فعالیتهای صفحهکلید نیز واکنش نشان دهد.
مهمترین Eventها:
keydown
keyupkeydown
وقتی کاربر یک کلید را فشار میدهد:
document.addEventListener("keydown", function () {
console.log("Key pressed");
});keyup
وقتی کاربر کلید را رها میکند:
document.addEventListener("keyup", function () {
console.log("Key released");
});دریافت کلید فشردهشده
Event Handler میتواند یک پارامتر دریافت کند.
مثلاً:
document.addEventListener("keydown", function (event) {
console.log(event.key);
});اگر کاربر کلید A را فشار دهد، مقدار:
aیا بسته به وضعیت صفحهکلید، کلید مربوطه در event.key قرار میگیرد.
event چیست؟
پارامتری که به Event Handler داده میشود، معمولاً اطلاعات مربوط به Event را در اختیار ما قرار میدهد.
مثلاً:
button.addEventListener("click", function (event) {
console.log(event);
});میتوانیم اطلاعات Event را مشاهده کنیم.
یکی از ویژگیهای مهم آن:
event.targetاست.
event.target
event.target عنصری را مشخص میکند که Event روی آن رخ داده است.
مثلاً:
button.addEventListener("click", function (event) {
console.log(event.target);
});با کلیک روی دکمه، خود دکمه در event.target قرار میگیرد.
تغییر متن عنصر با event.target
مثلاً:
button.addEventListener("click", function (event) {
event.target.textContent = "Clicked!";
});اکنون متن همان دکمه تغییر میکند.
این تکنیک زمانی که چند عنصر مشابه داریم بسیار مفید است.
Eventهای Input
یکی از مهمترین بخشهای تعامل با کاربر، دریافت اطلاعاتی است که کاربر در Input وارد میکند.
فرض کنید:
<input id="username" type="text">میتوانیم به Event input گوش دهیم:
const username =
document.getElementById("username");
username.addEventListener("input", function (event) {
console.log(event.target.value);
});هر بار که کاربر چیزی تایپ یا حذف کند، Event اجرا میشود.
تفاوت input و change
دو Event مهم برای کنترلهای فرم وجود دارد:
input
changeinput معمولاً با هر تغییر مقدار اجرا میشود.
مثلاً وقتی کاربر تایپ میکند:
A
Al
AliEvent چندین بار اجرا میشود.
اما change زمانی اجرا میشود که مقدار تغییر کرده و کاربر از کنترل خارج شود یا تغییر را نهایی کند؛ رفتار دقیق آن به نوع کنترل بستگی دارد.
مثلاً:
username.addEventListener("change", function (event) {
console.log(event.target.value);
});مثال عملی: نمایش لحظهای Input
HTML:
<input
id="name"
type="text"
placeholder="Enter your name"
>
<p id="result"></p>جاوااسکریپت:
const nameInput =
document.getElementById("name");
const result =
document.getElementById("result");
nameInput.addEventListener("input", function () {
result.textContent =
nameInput.value;
});اکنون هر چیزی که کاربر تایپ کند، همزمان در p نمایش داده میشود.
Event مربوط به Select
فرض کنید:
<select id="city">
<option value="tehran">Tehran</option>
<option value="istanbul">Istanbul</option>
<option value="dubai">Dubai</option>
</select>میتوانیم تغییر مقدار آن را دریافت کنیم:
const city =
document.getElementById("city");
city.addEventListener("change", function (event) {
console.log(event.target.value);
});اگر کاربر Istanbul را انتخاب کند:
istanbulدر Console نمایش داده میشود.
Event مربوط به Checkbox
HTML:
<input
id="terms"
type="checkbox"
>
<label for="terms">
Accept Terms
</label>جاوااسکریپت:
const terms =
document.getElementById("terms");
terms.addEventListener("change", function (event) {
console.log(event.target.checked);
});ویژگی:
checkedمشخص میکند Checkbox انتخاب شده است یا خیر.
مقدار آن true یا false خواهد بود.
Event مربوط به Radio
مثلاً:
<label>
<input
type="radio"
name="gender"
value="male"
>
Male
</label>
<label>
<input
type="radio"
name="gender"
value="female"
>
Female
</label>میتوانیم تغییر انتخاب را بررسی کنیم:
const radios =
document.querySelectorAll(
'input[name="gender"]'
);
for (const radio of radios) {
radio.addEventListener(
"change",
function (event) {
console.log(event.target.value);
}
);
}Event مربوط به Form
فرم یکی از مهمترین قسمتهای صفحات وب است.
HTML:
<form id="loginForm">
<input
type="text"
id="username"
>
<input
type="password"
id="password"
>
<button type="submit">
Login
</button>
</form>میتوانیم Event مربوط به ارسال فرم را دریافت کنیم:
const form =
document.getElementById("loginForm");
form.addEventListener(
"submit",
function (event) {
console.log("Form submitted");
}
);جلوگیری از ارسال پیشفرض فرم
وقتی یک فرم ارسال میشود، مرورگر معمولاً رفتار پیشفرض خودش را انجام میدهد.
در بسیاری از برنامههای جاوااسکریپت میخواهیم ابتدا اطلاعات فرم را بررسی کنیم.
برای جلوگیری از رفتار پیشفرض از:
event.preventDefault();استفاده میکنیم.
مثلاً:
form.addEventListener(
"submit",
function (event) {
event.preventDefault();
console.log("Form handled by جاوااسکریپت");
}
);اکنون مرورگر فرم را به شکل پیشفرض ارسال نمیکند.
این موضوع در ساخت فرمهای ورود، ثبتنام و فرمهای Ajax بسیار مهم است.
مثال عملی: فرم ورود ساده
HTML:
<form id="loginForm">
<input
id="username"
type="text"
placeholder="Username"
>
<input
id="password"
type="password"
placeholder="Password"
>
<button type="submit">
Login
</button>
<p id="message"></p>
</form>جاوااسکریپت:
const form =
document.getElementById("loginForm");
const username =
document.getElementById("username");
const password =
document.getElementById("password");
const message =
document.getElementById("message");
form.addEventListener(
"submit",
function (event) {
event.preventDefault();
if (
username.value.trim() === "" ||
password.value.trim() === ""
) {
message.textContent =
"Please fill all fields.";
return;
}
message.textContent =
"Form is valid.";
}
);در این مثال هنوز احراز هویت واقعی انجام نمیدهیم. هدف فقط آشنایی با Event و کنترل فرم است.
Event مربوط به صفحه
میتوانیم به Eventهای مربوط به خود صفحه نیز گوش دهیم.
مثلاً:
window.addEventListener(
"load",
function () {
console.log("Page loaded");
}
);Event load زمانی اجرا میشود که بارگذاری صفحه و منابع وابسته تکمیل شده باشد.
DOMContentLoaded
Event بسیار مهم دیگر:
DOMContentLoadedاست.
مثلاً:
document.addEventListener(
"DOMContentLoaded",
function () {
console.log("DOM is ready");
}
);این Event زمانی اجرا میشود که HTML صفحه Parse شده و DOM آماده شده باشد.
در بسیاری از موارد برای اجرای جاوااسکریپت پس از آماده شدن DOM کاربرد دارد.
تفاوت load و DOMContentLoaded
به صورت ساده:
DOMContentLoaded
↓
HTML parsed
↓
DOM readyاما:
load
↓
Page resources loaded
↓
Page fully loadedدر برنامههای معمول DOM، اغلب DOMContentLoaded برای اطمینان از آماده بودن ساختار HTML مناسب است.
حذف Event Listener
اگر یک Event Listener را اضافه کرده باشیم، میتوانیم در شرایط مناسب آن را حذف کنیم.
برای این کار از:
removeEventListener()استفاده میکنیم.
اما یک نکته بسیار مهم وجود دارد.
این روش:
button.addEventListener(
"click",
function () {
console.log("Clicked");
}
);و سپس:
button.removeEventListener(
"click",
function () {
console.log("Clicked");
}
);کار نمیکند.
چرا؟
چون این دو Function یکسان نیستند و هر بار یک Function جدید ساخته شده است.
روش صحیح removeEventListener
ابتدا تابع را در یک متغیر قرار میدهیم:
function handleClick() {
console.log("Clicked");
}سپس:
button.addEventListener(
"click",
handleClick
);و برای حذف:
button.removeEventListener(
"click",
handleClick
);اکنون Listener حذف میشود.
چند Event روی یک عنصر
میتوانیم چند Event روی یک عنصر داشته باشیم:
button.addEventListener(
"click",
function () {
console.log("Click");
}
);
button.addEventListener(
"mouseenter",
function () {
console.log("Mouse entered");
}
);
button.addEventListener(
"mouseleave",
function () {
console.log("Mouse left");
}
);هر Event رفتار مخصوص خودش را خواهد داشت.
چند Listener برای یک Event
میتوانیم حتی چند Listener برای یک Event اضافه کنیم:
button.addEventListener(
"click",
function () {
console.log("First");
}
);
button.addEventListener(
"click",
function () {
console.log("Second");
}
);با کلیک روی دکمه، هر دو Handler اجرا خواهند شد.
Event Bubbling چیست؟
یکی از مفاهیم مهم Eventها Event Bubbling است.
فرض کنید:
<div id="parent">
<button id="child">
Click
</button>
</div>اگر روی Button کلیک کنیم، Event فقط در Button باقی نمیماند و میتواند به عناصر والد نیز منتقل شود.
به صورت ساده:
button
↑
div
↑
body
↑
html
↑
documentاین رفتار را Event Bubbling مینامیم.
مثال Event Bubbling
const parent =
document.getElementById("parent");
const child =
document.getElementById("child");
parent.addEventListener(
"click",
function () {
console.log("Parent clicked");
}
);
child.addEventListener(
"click",
function () {
console.log("Child clicked");
}
);با کلیک روی Button ممکن است ابتدا:
Child clicked
Parent clickedرا مشاهده کنید.
توقف Event Bubbling
در شرایطی میتوانیم از:
event.stopPropagation();استفاده کنیم.
مثلاً:
child.addEventListener(
"click",
function (event) {
event.stopPropagation();
console.log("Child clicked");
}
);اکنون Event از Button به والد منتقل نمیشود.
این قابلیت باید با هدف مشخص استفاده شود و نباید بدون دلیل جلوی انتشار Eventها را بگیریم.
Event Delegation
یکی از تکنیکهای مهمتر DOM، Event Delegation است.
فرض کنید یک لیست داریم:
<ul id="users">
<li>Ali</li>
<li>Sara</li>
<li>Reza</li>
</ul>به جای اینکه برای تکتک liها Listener ایجاد کنیم، میتوانیم یک Listener روی والد قرار دهیم:
const users =
document.getElementById("users");
users.addEventListener(
"click",
function (event) {
if (event.target.tagName === "LI") {
console.log(
event.target.textContent
);
}
}
);در این روش Event از li به ul میرسد و ما با بررسی event.target متوجه میشویم کدام عنصر کلیک شده است.
Event Delegation مخصوصاً زمانی مفید است که عناصر زیادی داشته باشیم یا عناصر جدید را به صورت پویا ایجاد کنیم.
مثال عملی: لیست قابل کلیک
HTML:
<ul id="products">
<li>Product 1</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
<p id="selected"></p>جاوااسکریپت:
const products =
document.getElementById("products");
const selected =
document.getElementById("selected");
products.addEventListener(
"click",
function (event) {
if (event.target.tagName === "LI") {
selected.textContent =
`Selected: ${event.target.textContent}`;
}
}
);اکنون با کلیک روی هر محصول، نام آن در قسمت پایین نمایش داده میشود.
Eventهای پرکاربرد
جدول زیر چند Event مهم را نشان میدهد:
Eventکاربرد | |
|---|---|
| کلیک روی عنصر |
| دوبار کلیک |
| ورود Mouse به عنصر |
| خروج Mouse از عنصر |
| حرکت Mouse |
| فشردن Mouse |
| رها کردن Mouse |
| فشردن کلید |
| رها کردن کلید |
| تغییر لحظهای مقدار Input |
| تغییر مقدار کنترل |
| ارسال Form |
| تکمیل بارگذاری |
| آماده شدن DOM |
اشتباهات رایج در Eventها
اشتباه اول: اجرای فوری تابع
اشتباه:
button.addEventListener(
"click",
handleClick()
);صحیح:
button.addEventListener(
"click",
handleClick
);اشتباه دوم: انتخاب عنصر اشتباه
اگر:
const button =
document.getElementById("btn");مقدار null باشد، نمیتوانیم روی آن addEventListener() اجرا کنیم.
پس باید مطمئن شویم عنصر واقعاً وجود دارد و DOM آماده است.
اشتباه سوم: فراموش کردن preventDefault
در فرمها اگر رفتار پیشفرض مرورگر را نمیخواهیم:
event.preventDefault();را فراموش نکنیم.
اشتباه چهارم: استفاده اشتباه از value
برای Input معمولاً مقدار کاربر در:
input.valueقرار دارد.
مثلاً:
console.log(input.value);اشتباه پنجم: استفاده بیش از حد از mousemove
mousemove میتواند تعداد زیادی Event تولید کند.
اگر داخل آن عملیات سنگین انجام دهیم، ممکن است Performance صفحه کاهش پیدا کند.
تمرینها
تمرین ۱
یک Button ایجاد کنید که با کلیک روی آن متن یک h1 تغییر کند.
تمرین ۲
یک Button ایجاد کنید که با کلیک روی آن یک p نمایش داده شود.
تمرین ۳
یک Input ایجاد کنید و مقدار آن را با هر بار تایپ کاربر در یک p نمایش دهید.
تمرین ۴
یک Checkbox ایجاد کنید و مشخص کنید انتخاب شده است یا خیر.
تمرین ۵
یک Select با سه شهر ایجاد کنید و شهر انتخابشده را در صفحه نمایش دهید.
تمرین ۶
یک Form ایجاد کنید و هنگام Submit:
ارسال پیشفرض را متوقف کنید.
مقدار Username را دریافت کنید.
اگر Username خالی بود، پیام خطا نمایش دهید.
در غیر این صورت پیام موفقیت نمایش دهید.
تمرین ۷
یک Box ایجاد کنید.
وقتی Mouse وارد آن شد:
Mouse Enteredو وقتی خارج شد:
Mouse Leftنمایش دهید.
چالش عملی
یک Counter ساده با جاوااسکریپت ایجاد کنید.
HTML شما باید شامل:
Title
Count
Increase Button
Decrease Button
Reset Buttonباشد.
مثلاً:
Count: 0
[ Increase ]
[ Decrease ]
[ Reset ]رفتار برنامه:
با
Increaseعدد یک واحد افزایش پیدا کند.با
Decreaseعدد یک واحد کاهش پیدا کند.با
Resetعدد به صفر برگردد.مقدار Count با DOM در صفحه نمایش داده شود.
در این تمرین از مفاهیم زیر استفاده کنید:
DOM
addEventListener
click
Function
Variable
textContentجمعبندی
در این مقاله با Eventها در جاوااسکریپت آشنا شدیم.
Eventها به جاوااسکریپت اجازه میدهند به رفتار کاربر و اتفاقات مختلف مرورگر واکنش نشان دهد.
یاد گرفتیم:
Event چیست.
addEventListener()چگونه کار میکند.Event مربوط به
clickEvent مربوط به Mouse
Eventهای
keydownوkeyupEvent مربوط به
inputتفاوت
inputوchangeEvent مربوط به Checkbox و Radio
Event مربوط به Form
استفاده از
preventDefault()استفاده از
event.targetEventهای
loadوDOMContentLoadedحذف Listener با
removeEventListener()مفهوم Event Bubbling
استفاده از
stopPropagation()مفهوم Event Delegation
ترکیب Eventها با DOM
اکنون میتوانیم صفحات وبی بسازیم که فقط محتوای ثابت ندارند، بلکه به رفتار کاربر واکنش نشان میدهند.
نظرات
هنوز نظری ثبت نشده است.