تاروپود — خودآموز HTML و CSS

فصل ۴ از ۹

پیشرفت ترم
۰٪

ترم ۷ · پل به JavaScript

رویداد

فصل ۴پیش‌نمایش رایگان

در این فصل چه می‌سازی#

تا امروز هر خط JavaScript که نوشتی همان لحظهٔ باز شدنِ صفحه اجرا می‌شد و تمام. این فصل کدت را منتظر نگه می‌داری: با addEventListener به مرورگر می‌گویی «هر وقت روی این دکمه کلیک شد، این تکه‌کد را اجرا کن». آخرش صفحه‌ای داری که جواب می‌دهد — دکمه‌ای که پیامِ صفحه را عوض می‌کند، و بخشی که می‌گوید دقیقاً روی چه چیزی کلیک کرده‌ای.

یک دکمهٔ بزرگ که موج‌های صدا از آن به سمتِ یک گوشِ دوستانه می‌رود و بالای دکمه یک جرقهٔ کوچک روشن شده

آخر این فصل می‌توانی:

  • با addEventListener یک عنصر را به رویدادِ click گوش‌به‌زنگ کنی
  • functionی بنویسی که فقط وقتی رویداد اتفاق می‌افتد اجرا شود
  • با شیءِ event بفهمی رویداد دقیقاً روی کدام عنصر افتاده
  • فرقِ خرابیِ بی‌صدا (اسمِ رویدادِ غلط) و خرابیِ پر سر و صدا (selector غلط) را توضیح بدهی

قبل از شروع#

  • از فصل ۳: document.querySelector و textContent — کلِ این فصل روی همین دو سوار است.
  • از فصل ۲: const و template literal.
  • از ترم ۵: :hover — تا فرقش با کلیک را ببینی.

مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.

۱. کدی که منتظر می‌ماند#

در ترم ۵ با :hover دیدی صفحه می‌تواند به موس جواب بدهد — ولی فقط تا وقتی موس روی عنصر است؛ برش داری، همه‌چیز برمی‌گردد. کدِ JavaScript فصل‌های قبل هم برعکسش بود: یک بار موقعِ باز شدنِ صفحه اجرا می‌شد و دیگر هیچ.

چیزی که کم داریم انتظار است: کدی که الان اجرا نشود؛ بایستد و گوش بدهد تا یک رویداد بیفتد. رویداد یعنی یک اتفاق در صفحه — کلیک، تایپ، حرکتِ موس، فرستادنِ فرم. مرورگر همهٔ این اتفاق‌ها را می‌بیند؛ تو فقط باید بگویی به کدامش گوش بدهد و وقتی افتاد چه کند.

۲. addEventListener: گوش بده، بعد اجرا کن#

صفحهٔ آزمایشگاه این بخش را دارد:

<section class="magic">
  <h1>دکمهٔ جادویی</h1>
  <p class="message">هنوز هیچ اتفاقی نیفتاده.</p>
  <button class="magic-button">جادو کن</button>
</section>

در تبِ JS، اول مثل فصل ۳ دکمه و پیام را پیدا کن، بعد به دکمه گوش بده:

const button = document.querySelector('.magic-button');
const message = document.querySelector('.message');

button.addEventListener('click', function () {
  message.textContent = 'کلیک شنیده شد! این کار JavaScript بود.';
});

به addEventListener دو چیز می‌دهی. اولی یک string است: اسمِ رویدادی که باید بشنود — اینجا 'click'. دومی یک function است: تکه‌کدی بسته‌بندی‌شده که همین حالا اجرا نمی‌شود؛ تحویلِ مرورگر می‌دهی تا هر بار رویداد افتاد خودش اجرایش کند. به همین function می‌گویند listener.

چک کن: روی «جادو کن» کلیک کن — پیامِ بالای دکمه عوض می‌شود. قبل از کلیک هیچ خبری نیست: کد نوشته شده ولی منتظر است.

Checkpoint. قبل از ادامه، جواب بده: اگر سه بار پشتِ هم کلیک کنی، function چند بار اجرا می‌شود؟ (جواب: سه بار — هر رویداد یک اجرا. فقط چون هر بار همان متن را می‌نویسد، تغییری نمی‌بینی.)

💡 نکته: یک عنصر می‌تواند چند listener داشته باشد — یکی برای click، یکی برای رویدادی دیگر، حتی چند تا برای خودِ click. مرورگر همه را نگه می‌دارد و سرِ هر رویداد، همه را به‌ترتیب اجرا می‌کند. برای همین اسمش addEventListener است — «اضافه کن»، نه «جایگزین کن».

۳. حالا خرابش کن: رویدادی که هیچ‌وقت نمی‌افتد#

عمداً اسمِ رویداد را غلط بنویس:

button.addEventListener('clik', function () {
  message.textContent = 'کلیک شنیده شد! این کار JavaScript بود.';
});

کلیک کن. هیچ. نه پیام عوض می‌شود، نه خطایی در console هست. صفحه سالم به‌نظر می‌رسد و کاملاً خراب است — همان درسِ موذیِ ترم ۱، این‌بار در JavaScript.

🔧 اگر کار نکرد: مرورگر اعتراض نمی‌کند چون هر stringی می‌تواند اسمِ یک رویداد باشد؛ تو فقط به رویدادی گوش داده‌ای که هیچ‌وقت نمی‌افتد. مقایسه‌اش کن با selector غلط: اگر بنویسی querySelector('.magic-buton') چیزی پیدا نمی‌شود و addEventListener روی «هیچ» با یک خطای واقعی در console فریاد می‌زند: Cannot read properties of null. پس ترتیبِ رفعِ اشکال این است: اول console؛ اگر خطا بود selector ها را چک کن، اگر ساکت بود اسمِ رویداد را حرف‌به‌حرف بخوان.

۴. شیءِ event: رویداد با خودش خبر می‌آورد#

مرورگر وقتی listener ات را صدا می‌زند، یک بستهٔ اطلاعات هم دستش می‌دهد: شیءِ رویداد. کافی است بینِ پرانتزهای function یک اسم برایش بگذاری تا تحویلش بگیری. آن اسم یک قرارداد است، نه یک کلمهٔ جادویی — هر اسمی بگذاری کار می‌کند، ولی تقریباً همه event می‌نویسند و ما هم همین را می‌نویسیم. مهم‌ترین چیزی که تویش هست event.target است: عنصری که رویداد واقعاً رویش افتاد.

یک بخشِ دیگر به صفحه اضافه کن:

<section class="colors">
  <h2>کدام دکمه؟</h2>
  <button>قرمز</button>
  <button>آبی</button>
  <button>سبز</button>
  <p class="which">هنوز کلیک نکرده‌ای.</p>
</section>

و به‌جای سه listener برای سه دکمه، فقط یکی روی خودِ <section> بگذار:

const colors = document.querySelector('.colors');
const which = document.querySelector('.which');

colors.addEventListener('click', function (event) {
  which.textContent = `روی «${event.target.textContent}» کلیک کردی.`;
});

کلیک روی هر دکمه‌ای از دلِ <section> رد می‌شود، پس همان یک listener همه را می‌شنود — و event.target می‌گوید کدام بود.

چک کن: روی «آبی» کلیک کن؛ باید بنویسد: روی «آبی» کلیک کردی.

Checkpoint. قبل از ادامه، جواب بده: اگر روی خودِ جملهٔ «کدام دکمه؟» کلیک کنی چه می‌شود؟ (جواب: listener باز هم اجرا می‌شود و event.target همان <h2> است — target یعنی «چیزی که واقعاً زیرِ موس بود»، نه لزوماً یک دکمه.)

🤖 با AI: از دستیار AI ات بپرس: «غیر از click، پنج رویدادِ پرکاربردِ موس و صفحه‌کلید را هرکدام با یک جمله توضیح بده.» بعد دو تایش را همین‌جا در آزمایشگاه به‌جای 'click' بگذار و با چشمِ خودت چک کن که واقعاً همان‌طور که AI گفت رفتار می‌کنند.

کد کاملِ این فصل#

<!-- index.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>دکمهٔ جادویی</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <main>
      <section class="magic">
        <h1>دکمهٔ جادویی</h1>
        <p class="message">هنوز هیچ اتفاقی نیفتاده.</p>
        <button class="magic-button">جادو کن</button>
      </section>

      <section class="colors">
        <h2>کدام دکمه؟</h2>
        <button>قرمز</button>
        <button>آبی</button>
        <button>سبز</button>
        <p class="which">هنوز کلیک نکرده‌ای.</p>
      </section>
    </main>
    <script src="script.js"></script>
  </body>
</html>
/* styles.css */
body {
  font-family: Tahoma, sans-serif;
  background-color: #f6edda;
  color: #2c2114;
  line-height: 1.7;
  padding: 24px;
}

section {
  background-color: #ffffff;
  border: 1px solid #d8ccae;
  border-radius: 12px;
  padding: 16px;
  max-width: 360px;
  margin-block-end: 16px;
}

button {
  font-family: inherit;
  font-size: 1rem;
  padding: 8px 16px;
  border: 1px solid #b98a2f;
  border-radius: 8px;
  background-color: #f3d491;
  cursor: pointer;
}
// script.js
const button = document.querySelector('.magic-button');
const message = document.querySelector('.message');

button.addEventListener('click', function () {
  message.textContent = 'کلیک شنیده شد! این کار JavaScript بود.';
});

const colors = document.querySelector('.colors');
const which = document.querySelector('.which');

colors.addEventListener('click', function (event) {
  which.textContent = `روی «${event.target.textContent}» کلیک کردی.`;
});

واژه‌های تازهٔ این فصل#

کلمه تلفظ به حروف فارسی یعنی چه
event ایوِنت یک اتفاق در صفحه: کلیک، تایپ، حرکتِ موس
addEventListener اَد ایوِنت لیسِنِر به عنصر می‌گوید «به این رویداد گوش بده و این function را اجرا کن»
listener لیسِنِر functionی که منتظرِ یک رویداد می‌ماند
function فانکشِن تکه‌کدی بسته‌بندی‌شده که بعداً اجرا می‌شود
event.target ایوِنت تارگِت عنصری که رویداد واقعاً رویش اتفاق افتاد

تمرین‌ها

اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.

در فصل بعد#

الان صفحه‌ات می‌شنود. فصل بعد قشنگ‌ترین قراردادِ دنیای front-end را می‌بینی: JavaScript فقط یک class را روشن و خاموش می‌کند و همهٔ ظاهر — رنگ، حرکت، حالتِ شب — کارِ همان CSS ای است که شش ترم ساختی. یک خط classList.toggle و استایل‌هایت زنده می‌شوند.

به آخر این فصل رسیدی!

اگر ساختی و جواب داد، این دکمه مال توست.