در این فصل چه میسازی#
این فصل JavaScript را به صفحه وصل میکند: با document.querySelector عنصر را با همان selector های CSS که از ترم ۲ بلدی پیدا میکنی، متنش را با textContent میخوانی و عوض میکنی، و ظاهرش را با classList و style تغییر میدهی. آخر فصل کارتی داری که وقتی صفحه باز میشود، JavaScript تیترش را عوض میکند، وضعیتش را مینویسد و برجستهاش میکند — بدون اینکه دستت به HTML بخورد.

آخر این فصل میتوانی:
- عنصر را با
querySelectorو selector های آشنا پیدا کنی و در یکconstنگه داری textContentیک عنصر را بخوانی و عوض کنی- با
classListیک class آماده را روشن و خاموش کنی و باstyleیک property را مستقیم بدهی - خطای
nullرا بشناسی و دو علتِ همیشگیاش را پیدا کنی
قبل از شروع#
- از ترم ۲: selector ها —
.class، نوع، descendant.querySelectorدقیقاً همین زبان را حرف میزند. - از فصل ۱: قانونِ «
<script>آخرِ<body>» — امروز بالاخره میفهمی چرا. - از فصل ۲:
constو template literal.
مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.
۱. پلی به چیزی که از قبل بلدی#
خبرِ خوبِ این فصل: چیزِ تازهای برای «پیدا کردن» یاد نمیگیری. document.querySelector یک جمله بیشتر نیست: «ای سند، اولین عنصری را که به این selector میخورد بده به من.» و selector همان زبانی است که دو ترم است با آن CSS مینویسی.
HTML کارتِ این فصل این است:
<article class="card">
<h1 class="card__title">کارت من</h1>
<p class="card__status">هنوز خبری نیست.</p>
</article>
حالا در تب JS، تیتر را پیدا کن و متنش را بخوان:
const title = document.querySelector(".card__title");
console.log(title.textContent);
querySelector خودِ عنصر را برمیگرداند و ما در جعبهٔ title نگهش میداریم — همان const فصل قبل. بعد title.textContent یعنی «متنِ داخل این عنصر».
✅ چک کن: در console نوشته: کارت من. JavaScript صفحه را خواند.
اگر selector به چند عنصر بخورد چه؟ querySelector فقط اولین را میدهد و تمام.
۲. نوشتن روی صفحه — قولِ فصل ۱#
خواندن تماشاست؛ نوشتن قدرت است. به textContent مقدار بده تا متنِ عنصر عوض شود:
title.textContent = "کارتِ زنده";
const writer = "JavaScript";
const status = document.querySelector(".card__status");
status.textContent = `این متن را ${writer} نوشت، نه HTML.`;
✅ چک کن: روی خودِ صفحه، تیترِ کارت شده «کارتِ زنده» و زیرش نوشته «این متن را JavaScript نوشت، نه HTML.» — template literal فصل قبل هم سرِ کار آمد.
این همان راهِ درستی است که فصل ۱ قولش را دادیم: document.write فقط بلد بود متن را تهِ صفحه بریزد؛ اینجا دقیقاً همان عنصری را که میخواهی نشانه میگیری و عوض میکنی.
۳. وقتی querySelector چیزی پیدا نمیکند#
حالا مهمترین خرابیِ این فصل را عمداً بساز. در selector یک غلطِ تایپی بگذار:
const title = document.querySelector(".card__titel");
console.log(title.textContent);
صفحه بیتغییر میماند و console سرخ میشود:
Uncaught TypeError: Cannot read properties of null (reading 'textContent')
at script.js:3
🔧 اگر کار نکرد: این پیام دو تکه دارد.
nullیعنی «هیچچیز»: وقتیquerySelectorعنصری با آن selector پیدا نکند، بیسروصداnullبرمیگرداند و شکایتی نمیکند. خطا تازه وقتی میترکد که از دلِ آن هیچچیز، چیزی بخواهی — اینجاreading 'textContent'. پس ترجمهٔ واقعیِ این پیام تقریباً همیشه این است: «selector ات به هیچ عنصری نخورد.» selector را حرفبهحرف با HTML مقایسه کن:titelبایدtitleباشد. (در آزمایشگاه، جایscript.js:3چیزی مثلabout:srcdocبا شمارهخطِ دیگری مینشیند — سندِ پیشنمایشِ آزمایشگاه است؛ خطا را با متنِ پیام بشناس، نه با فایل و شمارهخط.)
و یک دامِ دوم با همان علامت: selector ات درست است ولی <script> را در <head> گذاشتهای. مرورگر صفحه را از بالا به پایین میخواند؛ در <head> هنوز هیچ <article> ای ساخته نشده، پس querySelector در آن لحظه راست میگوید: «چیزی نیست!» این همان چراییِ قانونِ فصل ۱ است: <script> آخرِ <body> مینشیند تا وقتی اجرا میشود، همهٔ عنصرها ساخته شده باشند.
⚠️ مواظب باش: نقطهٔ اولِ selector جزئی از خودِ selector است — همانطور که در CSS بود.
querySelector("card__title")بدونِ نقطه یعنی «تگی به نامِ card__title»، که وجود ندارد و بازnullمیگیری.
اگر هر دو مظنون را چک کردی و هنوز گیر بودی، وقتِ کمکگرفتن است:
🤖 با AI: وقتی به
nullخوردی و پیدا نکردی چرا، HTML ات و خطِquerySelectorرا با هم به دستیار AI ات بده و بپرس: «چرا این selector به چیزی نمیخورد؟» جوابش را با دو مظنونِ همین فصل بسنج — غلطِ تایپی و جای<script>— و فقط وقتی قبولش کن که بعد از اصلاح، خطا واقعاً از console رفته باشد.
Checkpoint. قبل از ادامه، جواب بده: اگر صفحه دو <p class="card__status"> داشته باشد، querySelector(".card__status") متنِ کدام را عوض میکند؟ (جواب: فقط اولین را. برای گرفتنِ دومی یک نشانیِ دقیقتر لازم داری — مثلاً یک id.)
۴. تغییرِ ظاهر: classList و style#
برای ظاهر دو دستگیره داری. اولی و بهترش classList است: class ای را که استایلش را از قبل در CSS نوشتهای روشن یا خاموش میکند. فرض کن در styles.css این را داری:
.highlight {
background-color: #fff3c4;
border-color: #e0a800;
}
حالا از JS روشنش کن:
const card = document.querySelector(".card");
card.classList.add("highlight");
classList.add این class را به عنصر اضافه میکند — انگار خودت در HTML نوشته باشی — و classList.remove("highlight") برش میدارد.
دستگیرهٔ دوم style است: یک property را مستقیم روی عنصر میگذارد:
status.style.color = "#1b7a43";
فقط حواست باشد property های دوکلمهای مثل background-color در JS به شکلِ backgroundColor نوشته میشوند — خط تیره در اسمِ JavaScript مجاز نیست.
✅ چک کن: کارت زردِ برجسته شد و جملهٔ وضعیت سبز. همهٔ اینها هنگام بازشدنِ صفحه اتفاق افتاد.
💡 نکته: تا میتوانی
classList، نهstyle. استایل باید در CSS زندگی کند — همان درسِ ترم ۶ — و JS فقط کلید را بزند.styleرا برای وقتی نگه دار که مقدار واقعاً از دلِ JS میآید.
کد کاملِ این فصل#
<!-- 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>
<article class="card">
<h1 class="card__title">کارت من</h1>
<p class="card__status">هنوز خبری نیست.</p>
</article>
</main>
<script src="script.js"></script>
</body>
</html>
فایل styles.css:
/* styles.css */
body {
font-family: Tahoma, sans-serif;
background-color: #f6edda;
color: #2c2114;
line-height: 1.7;
padding: 24px;
}
.card {
background-color: #ffffff;
border: 1px solid #d8ccae;
border-radius: 12px;
padding: 16px;
max-width: 360px;
}
.highlight {
background-color: #fff3c4;
border-color: #e0a800;
}
و script.js:
// script.js — kart-e zende
const title = document.querySelector(".card__title");
console.log(title.textContent);
title.textContent = "کارتِ زنده";
const writer = "JavaScript";
const status = document.querySelector(".card__status");
status.textContent = `این متن را ${writer} نوشت، نه HTML.`;
const card = document.querySelector(".card");
card.classList.add("highlight");
status.style.color = "#1b7a43";
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
document |
داکیومِنت | خودِ صفحه، از نگاه JavaScript |
querySelector |
کوئریسِلِکتور | اولین عنصری را که به یک selector میخورد برمیگرداند |
textContent |
تکستکانتِنت | متنِ داخل یک عنصر — هم خواندنی، هم نوشتنی |
null |
نال | مقدارِ «هیچچیز»؛ جوابِ querySelector وقتی چیزی پیدا نکند |
classList |
کلسلیست | فهرست class های یک عنصر، با add و remove |
style |
استایل | دادنِ مستقیمِ یک property به یک عنصر از داخل JS |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
همهٔ تغییرهای این فصل هنگامِ بازشدنِ صفحه اجرا شدند — کاربر هنوز نقشی ندارد. فصل بعد کد را به دستِ او میدهیم: با addEventListener و رویدادِ click، تکهکدت فقط وقتی اجرا میشود که کاربر واقعاً کلیک کند — و صفحه برای اولین بار به معنای کامل تعاملی میشود.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.