آکادمی بنو/آموزش JavaScript

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

یعنی:

  1. کدام عنصر؟

  2. به چه رویدادی گوش بده؟

  3. هنگام رخ دادن رویداد چه کاری انجام بده؟

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
keyup

keydown

وقتی کاربر یک کلید را فشار می‌دهد:

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
change

input معمولاً با هر تغییر مقدار اجرا می‌شود.

مثلاً وقتی کاربر تایپ می‌کند:

A
Al
Ali

Event چندین بار اجرا می‌شود.

اما 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کاربرد

click

کلیک روی عنصر

dblclick

دوبار کلیک

mouseenter

ورود Mouse به عنصر

mouseleave

خروج Mouse از عنصر

mousemove

حرکت Mouse

mousedown

فشردن Mouse

mouseup

رها کردن Mouse

keydown

فشردن کلید

keyup

رها کردن کلید

input

تغییر لحظه‌ای مقدار Input

change

تغییر مقدار کنترل

submit

ارسال Form

load

تکمیل بارگذاری

DOMContentLoaded

آماده شدن 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:

  1. ارسال پیش‌فرض را متوقف کنید.

  2. مقدار Username را دریافت کنید.

  3. اگر Username خالی بود، پیام خطا نمایش دهید.

  4. در غیر این صورت پیام موفقیت نمایش دهید.

تمرین ۷

یک 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 مربوط به click

  • Event مربوط به Mouse

  • Eventهای keydown و keyup

  • Event مربوط به input

  • تفاوت input و change

  • Event مربوط به Checkbox و Radio

  • Event مربوط به Form

  • استفاده از preventDefault()

  • استفاده از event.target

  • Eventهای load و DOMContentLoaded

  • حذف Listener با removeEventListener()

  • مفهوم Event Bubbling

  • استفاده از stopPropagation()

  • مفهوم Event Delegation

  • ترکیب Eventها با DOM

اکنون می‌توانیم صفحات وبی بسازیم که فقط محتوای ثابت ندارند، بلکه به رفتار کاربر واکنش نشان می‌دهند.

۰۰

نظرات

کد در دسترس نیست

هنوز نظری ثبت نشده است.