آموزش جاوا اسکریپت مبتدی : مقدمهای بر اسکریپتنویسی DOM
هنگام نوشتن صفحات وب و برنامهها، یکی از رایجترین کارهایی که میخواهید انجام دهید، تغییر ساختار سند به نوعی است. این کار معمولاً با دستکاری مدل شیء سند (DOM) از طریق مجموعهای از APIهای داخلی مرورگر برای کنترل HTML و اطلاعات استایلدهی انجام میشود. در این مقاله شما را با اسکریپتنویسی DOM آشنا خواهیم کرد.
مرورگرهای وب، نرمافزارهای بسیار پیچیدهای با بخشهای متحرک زیادی هستند که بسیاری از آنها توسط یک توسعهدهنده وب با استفاده از جاوا اسکریپت قابل کنترل یا دستکاری نیستند. ممکن است فکر کنید که چنین محدودیتهایی چیز بدی هستند، اما مرورگرها به دلایل خوبی، عمدتاً حول محور امنیت، قفل شدهاند. تصور کنید که یک وبسایت میتواند به رمزهای عبور ذخیره شده یا سایر اطلاعات حساس شما دسترسی پیدا کند و مانند شما وارد وبسایتها شود؟
با وجود محدودیتها، APIهای وب هنوز به ما امکان دسترسی به عملکردهای زیادی را میدهند که ما را قادر میسازد کارهای زیادی را با صفحات وب انجام دهیم. چند نکته واقعاً واضح وجود دارد که مرتباً در کد خود به آنها اشاره خواهید کرد - نمودار زیر را در نظر بگیرید که بخشهای اصلی یک مرورگر را که مستقیماً در مشاهده صفحات وب دخیل هستند، نشان میدهد:

- پنجره، تب مرورگری را نشان میدهد که یک صفحه وب در آن بارگذاری میشود؛ این در جاوا اسکریپت توسط شیء Window نمایش داده میشود. با استفاده از متدهای موجود در این شیء، میتوانید کارهایی مانند بازگرداندن اندازه پنجره (به و مراجعه کنید)، دستکاری سند بارگذاری شده در آن پنجره، ذخیره دادههای خاص آن سند در سمت کلاینت (به عنوان مثال با استفاده از یک پایگاه داده محلی یا مکانیسم ذخیرهسازی دیگر)، اتصال یک کنترلکننده رویداد به پنجره فعلی و موارد دیگر را انجام دهید.
- ناوبر، وضعیت و هویت مرورگر را همانطور که در وب وجود دارد، نشان میدهد. در جاوا اسکریپت، این توسط شیء Navigator نمایش داده میشود. میتوانید از این شیء برای بازیابی مواردی مانند زبان ترجیحی کاربر، جریان رسانهای از وبکم کاربر و غیره استفاده کنید.
- سند (که توسط DOM در مرورگرها نمایش داده میشود) صفحه واقعی بارگذاری شده در پنجره است و در جاوا اسکریپت توسط شیء Document نمایش داده میشود. شما میتوانید از این شیء برای بازگرداندن و دستکاری اطلاعات مربوط به HTML و CSS که سند را تشکیل میدهند، استفاده کنید، برای مثال، ارجاعی به یک عنصر در DOM دریافت کنید، محتوای متنی آن را تغییر دهید، سبکهای جدیدی به آن اعمال کنید، عناصر جدید ایجاد کنید و آنها را به عنوان فرزند به عنصر فعلی اضافه کنید، یا حتی آن را به طور کلی حذف کنید.
در این مقاله، ما بیشتر بر دستکاری سند تمرکز خواهیم کرد، اما چند نکته مفید دیگر را نیز در کنار آن نشان خواهیم داد.
بیایید خلاصهای از مدل شیء سند (DOM) ارائه دهیم، که قبلاً در این دوره به آن پرداختهایم. سندی که در حال حاضر در هر یک از تبهای مرورگر شما بارگذاری میشود، توسط یک DOM نمایش داده میشود. این یک نمایش "ساختار درختی" است که توسط مرورگر ایجاد میشود و امکان دسترسی آسان به ساختار HTML را توسط زبانهای برنامهنویسی فراهم میکند - به عنوان مثال، خود مرورگر از آن برای اعمال استایل و سایر اطلاعات به عناصر صحیح هنگام رندر کردن یک صفحه استفاده میکند و توسعهدهندگانی مانند شما میتوانند DOM را پس از رندر شدن صفحه با جاوا اسکریپت دستکاری کنند.
ما یک صفحه نمونه در ایجاد کردهایم (همچنین میتوانید آن را به صورت زنده مشاهده کنید). سعی کنید آن را در مرورگر خود باز کنید - این یک صفحه بسیار ساده است که شامل یک عنصر است که در داخل آن میتوانید یک تصویر و یک پاراگراف با یک لینک در داخل آن پیدا کنید. کد منبع HTML به این شکل است:
از طرف دیگر، DOM به این شکل است:

این نمودار درختی DOM با استفاده از نمایشگر زنده DOM ایان هیکسون ایجاد شده است.
هر ورودی در درخت، یک گره یا node نامیده میشود. در نمودار بالا میتوانید ببینید که برخی از گرهها نشاندهنده عناصر (شناسایی شده به عنوان HTML، HEAD، META و غیره) و برخی دیگر نشاندهنده متن (شناسایی شده به عنوان #text) هستند. انواع دیگری از گرهها نیز وجود دارند، اما اینها اصلیترین مواردی هستند که با آنها مواجه خواهید شد.
گرهها همچنین بر اساس موقعیتشان در درخت نسبت به سایر گرهها ارجاع داده میشوند:
- گره ریشه: گره بالایی در درخت، که در مورد HTML همیشه گره HTML است (سایر واژگان نشانهگذاری مانند SVG و XML سفارشی عناصر ریشه متفاوتی خواهند داشت).
- گره فرزند: گرهای که مستقیماً درون گره دیگری قرار دارد. به عنوان مثال، IMG در مثال بالا فرزند SECTION است.
- گره فرزند: گرهای که در هر جایی درون گره دیگری قرار دارد. به عنوان مثال، IMG در مثال بالا فرزند SECTION است و همچنین یک فرزند است. IMG فرزند BODY نیست، زیرا دو سطح پایینتر از آن در درخت است، اما از نسل BODY است.
- گره والد: گرهای که گره دیگری درون خود دارد. برای مثال، BODY گره والد SECTION در مثال بالا است.
گرههای خواهر و برادر: گرههایی که در درخت DOM در یک سطح زیر یک گره والد قرار دارند. برای مثال، IMG و P در مثال بالا خواهر و برادر هستند.
آشنایی با این اصطلاحات قبل از کار با DOM مفید است، زیرا تعدادی از اصطلاحات کد که با آنها مواجه خواهید شد از آنها استفاده میکنند. همچنین در CSS با آنها مواجه خواهید شد (برای مثال، انتخابگر فرزند، انتخابگر فرزند).
انجام برخی دستکاریهای اولیه DOM
برای شروع یادگیری در مورد دستکاری DOM، بیایید با یک مثال عملی شروع کنیم.
۱- یک کپی محلی از صفحه و تصویری که همراه آن است، بگیرید.
۲- یک عنصر درست بالای تگ بسته اضافه کنید.
۳- برای دستکاری یک عنصر درون DOM، ابتدا باید آن را انتخاب کنید و یک ارجاع به آن را درون یک متغیر ذخیره کنید. درون عنصر script خود، خط زیر را اضافه کنید:
۴- حالا که مرجع عنصر را در یک متغیر ذخیره کردهایم، میتوانیم با استفاده از ویژگیها و متدهای موجود در آن، شروع به دستکاری آن کنیم (این ویژگیها در رابطهایی مانند HTMLAnchorElement در مورد عنصر ، رابط والد عمومیتر آن HTMLElement و Node - که نشان دهنده همه گرهها در یک DOM است - تعریف شدهاند). اول از همه، بیایید متن داخل لینک را با بهروزرسانی مقدار ویژگی تغییر دهیم. خط زیر را زیر خط قبلی اضافه کنید:
همچنین باید آدرس اینترنتی (URL) لینک را تغییر دهیم تا وقتی روی آن کلیک میشود، به جای اشتباهی نرود. خط زیر را دوباره در پایین اضافه کنید:
توجه داشته باشید که، مانند بسیاری از موارد در جاوا اسکریپت، روشهای زیادی برای انتخاب یک عنصر و ذخیره ارجاع به آن در یک متغیر وجود دارد.
رویکرد مدرن پیشنهادی است. این روش راحت است زیرا به شما امکان میدهد عناصر را با استفاده از انتخابگرهای CSS انتخاب کنید. فراخوانی فوق با اولین عنصر که در سند ظاهر میشود، مطابقت خواهد داشت. اگر میخواستید چندین عنصر را مطابقت داده و کارهایی را روی آنها انجام دهید، میتوانید از استفاده کنید که با هر عنصری در سند که با انتخابگر مطابقت دارد، مطابقت دارد و ارجاعات به آنها را در یک شیء آرایه مانند به نام NodeList ذخیره میکند.
روشهای قدیمیتری برای گرفتن ارجاعات عنصر وجود دارد، مانند:
، که عنصری را با مقدار ویژگی id داده شده انتخاب میکند، به عنوان مثال، . شناسه به عنوان یک پارامتر به تابع ارسال میشود، یعنی که یک شیء آرایهمانند شامل تمام عناصر موجود در صفحه از یک نوع مشخص، مثلاً <p>ها، <a>ها و غیره، را برمیگرداند. نوع عنصر به عنوان یک پارامتر به تابع ارسال میشود، یعنی .
این دو در مرورگرهای قدیمیتر بهتر از روشهای مدرن مانند کار میکنند، اما به راحتی آنها نیستند. نگاهی بیندازید و ببینید چه روشهای دیگری میتوانید پیدا کنید!
ایجاد و قرار دادن گرههای جدید
موارد بالا کمی از آنچه میتوانید انجام دهید را به شما نشان داد، اما بیایید فراتر برویم و ببینیم چگونه میتوانیم عناصر جدید ایجاد کنیم.
1- به مثال فعلی برگردیم، بیایید با گرفتن یک ارجاع به عنصر خود شروع کنیم - کد زیر را در انتهای اسکریپت موجود خود اضافه کنید (همین کار را با خطوط دیگر نیز انجام دهید):
2- حالا بیایید با استفاده از یک پاراگراف جدید ایجاد کنیم و به همان روش قبلی، مقداری محتوای متنی به آن بدهیم:
اکنون میتوانید با استفاده از پاراگراف جدید را در انتهای بخش اضافه کنید:
در نهایت برای این بخش، بیایید یک گره متنی به پاراگرافی که لینک درون آن قرار دارد اضافه کنیم تا جمله به خوبی کامل شود. ابتدا گره متنی را با استفاده از ایجاد میکنیم:
حالا یک ارجاع به پاراگرافی که لینک درون آن قرار دارد میگیریم و گره متنی را به آن اضافه میکنیم:
این بیشتر چیزی است که برای اضافه کردن گرهها به DOM نیاز دارید - هنگام ساخت رابطهای پویا از این متدها استفاده زیادی خواهید کرد (بعداً به چند مثال نگاه خواهیم کرد).
ممکن است مواقعی پیش بیاید که بخواهید گرهها را جابجا کنید یا آنها را به طور کلی از DOM حذف کنید. این کاملاً امکانپذیر است.
اگر میخواستیم پاراگراف را به همراه لینک داخل آن به پایین بخش منتقل کنیم، میتوانستیم این کار را انجام دهیم:
این کار پاراگراف را به پایین بخش منتقل میکند. شاید فکر میکردید که یک کپی دوم از آن ایجاد میکند، اما اینطور نیست - linkPara مرجعی به تنها کپی آن پاراگراف است. اگر میخواستید یک کپی ایجاد کنید و آن را نیز اضافه کنید، باید از استفاده کنید.
حذف یک گره نیز بسیار ساده است، حداقل زمانی که به گرهای که قرار است حذف شود و والد آن اشارهای دارید. در مورد فعلی ما، ما فقط از استفاده میکنیم، مانند این:
وقتی میخواهید یک گره را فقط بر اساس ارجاع به خودش حذف کنید، که نسبتاً رایج است، میتوانید از استفاده کنید:
این روش در مرورگرهای قدیمی پشتیبانی نمیشود. آنها هیچ روشی برای دستور دادن به یک گره برای حذف خود ندارند، بنابراین باید موارد زیر را انجام دهید:
سعی کنید خطوط بالا را به کد خود اضافه کنید.
دستکاری سبکهای CSS از طریق جاوا اسکریپت به روشهای مختلفی امکانپذیر است.
برای شروع، میتوانید با استفاده از لیستی از تمام stylesheetهای متصل به یک سند را دریافت کنید، که یک شیء آرایه مانند با اشیاء CSSStyleSheet را برمیگرداند. سپس میتوانید سبکها را به دلخواه اضافه/حذف کنید. با این حال، ما قصد نداریم در مورد این ویژگیها توضیح بیشتری بدهیم زیرا آنها روشی نسبتاً قدیمی و دشوار برای دستکاری سبک هستند. روشهای بسیار آسانتری وجود دارد.
اولین راه، اضافه کردن سبکهای درونخطی به طور مستقیم به عناصری است که میخواهید به صورت پویا سبکدهی کنید. این کار با ویژگی انجام میشود که شامل اطلاعات سبکبندی درونخطی برای هر عنصر در سند است. میتوانید ویژگیهای این شیء را برای بهروزرسانی مستقیم سبکهای عنصر تنظیم کنید.
به عنوان مثال، سعی کنید این خطوط را به مثال در حال انجام ما اضافه کنید:
صفحه را دوباره بارگذاری کنید و خواهید دید که استایلها به پاراگراف اعمال شدهاند. اگر در مرورگر خود به آن پاراگراف نگاه کنید، خواهید دید که این خطوط در واقع استایلهای درونخطی را به سند اضافه میکنند:
توجه کنید که چگونه نسخههای ویژگیهای جاوا اسکریپت از سبکهای CSS با حروف کوچک شتری نوشته میشوند در حالی که نسخههای CSS با خط فاصله (kebab-case) نوشته میشوند (مثلاً backgroundColor در مقابل ). مطمئن شوید که این موارد را با هم قاطی نمیکنید، در غیر این صورت کار نخواهد کرد.
یک روش رایج دیگر برای دستکاری پویای سبکها در سند شما وجود دارد، که نوشتن سبکها در یک stylesheet جداگانه و ارجاع به آن سبکها با اضافه کردن/حذف کردن نام کلاس است.
پنج خط قبلی را که به جاوا اسکریپت اضافه کردهاید حذف کنید.
کد زیر را در HTML خود اضافه کنید:
برای افزودن این نام کلاس به عنصر خود، از متد مربوط به classList عنصر استفاده کنید:
صفحه خود را رفرش کنید، هیچ تغییری نخواهید دید - CSS هنوز روی پاراگراف اعمال میشود، اما این بار با دادن کلاسی که توسط قانون CSS ما انتخاب شده است، نه به عنوان سبکهای CSS درونخطی.
اینکه کدام روش را انتخاب کنید به خودتان بستگی دارد؛ هر دو مزایا و معایب خود را دارند. روش اول به تنظیمات کمتری نیاز دارد و برای کاربردهای ساده مناسب است، در حالی که روش دوم اصولیتر است (بدون ترکیب CSS و جاوا اسکریپت، بدون سبکهای درونخطی، که به عنوان یک عمل بد دیده میشوند). همانطور که شروع به ساخت برنامههای بزرگتر و پیچیدهتر میکنید، احتمالاً بیشتر از روش دوم استفاده خواهید کرد، اما واقعاً به شما بستگی دارد.
در این مرحله، ما واقعاً هیچ کار مفیدی انجام ندادهایم! استفاده از جاوا اسکریپت برای ایجاد محتوای استاتیک هیچ فایدهای ندارد - میتوانید آن را فقط در HTML خود بنویسید و از جاوا اسکریپت استفاده نکنید. این روش پیچیدهتر از HTML است و ایجاد محتوای شما با جاوا اسکریپت مشکلات دیگری نیز دارد (مانند قابل خواندن نبودن توسط موتورهای جستجو).
در بخش بعدی به استفاده عملیتر از APIهای DOM خواهیم پرداخت.