معرفی DOM و کاربرد آن در JavaScript

DOM یا Document Object Model، یک رابط برنامه‌نویسی مستقل از زبان است که مرورگرها برای نمایش ساختار درختی یک سند HTML یا XML از آن استفاده می‌کنند. این مدل به جاوا اسکریپت امکان می‌دهد تا به عناصر صفحه وب دسترسی یافته و آنها را دستکاری کند و صفحات پویا و تعاملی ایجاد کند.

مدل شیء سند (DOM) به‌عنوان یک واسط حیاتی، پل ارتباطی میان محتوای ثابت یک صفحه وب و قابلیت‌های تعاملی جاوا اسکریپت است. این ابزار به توسعه‌دهندگان فرانت‌اند این امکان را می‌دهد که ساختار، محتوا و استایل صفحات وب را در لحظه تغییر دهند و تجربه‌ای غنی و پاسخگو برای کاربران فراهم آورند. در این مقاله به بررسی عمیق مفهوم معرفی DOM و کاربرد آن در JavaScript، مزایای آن، متدهای کلیدی برای دسترسی و دستکاری عناصر، و همچنین بهترین روش‌ها برای بهینه‌سازی عملکرد در برنامه‌نویسی وب می‌پردازیم.

DOM چیست؟ درک عمیق مدل شی‌گرای سند

Document Object Model (DOM) سرنامی برای «مدل شی‌گرای سند» است. DOM یک استاندارد تعریف‌شده توسط کنسرسیوم جهانی وب (W3C) است که یک رابط برنامه‌نویسی کاربردی (API) مستقل از زبان و پلتفرم برای تعامل با اسناد HTML و XML فراهم می‌کند. این مدل، سند وب را به شکل یک ساختار درختی از گره‌ها (Node Tree) نمایش می‌دهد؛ هر عنصر HTML، هر ویژگی، و حتی هر قطعه متن در سند، به یک گره یا شیء در این درخت تبدیل می‌شود.

این نمایش شیءگرا، تفاوت اصلی DOM با کد HTML خام است. در حالی که HTML تنها ساختار اولیه و محتوای ثابت را تعریف می‌کند، DOM یک مدل حافظه قابل دستکاری از آن سند را ارائه می‌دهد. این مدل به زبان‌های اسکریپت‌نویسی مانند جاوا اسکریپت اجازه می‌دهد تا به محتویات صفحه وب “نگاه کنند”، آنها را “تغییر دهند”، “اضافه کنند” یا “حذف کنند”. به این ترتیب، DOM به عنوان واسطی عمل می‌کند که آموزش جاوا اسکریپت  از طریق آن می‌تواند صفحات وب را به موجودیت‌هایی پویا و تعاملی تبدیل کند.

DOM به عنوان یک API، سند وب را از یک متن ثابت به یک مجموعه از اشیاء قابل برنامه‌ریزی تبدیل می‌کند و امکان ایجاد تعاملات پیچیده کاربر را فراهم می‌آورد.

ارتباط تنگاتنگ DOM و JavaScript: قلب تعامل وب

جاوا اسکریپت به عنوان زبان اصلی سمت کاربر (Client-Side) برای ایجاد صفحات وب پویا، بدون DOM عملاً بی‌معنی خواهد بود. معرفی DOM و کاربرد آن در JavaScript دقیقاً در همین نقطه تلاقی پیدا می‌کند. جاوا اسکریپت از DOM برای “دیدن” و “دستکاری” هر جزء از ساختار، محتوا و استایل صفحات وب استفاده می‌کند.

زمانی که یک مرورگر صفحه HTML را بارگذاری می‌کند، آن را به یک درخت DOM تبدیل کرده و یک شیء سراسری به نام document ایجاد می‌کند. این شیء document، نقطه ورود جاوا اسکریپت به کل ساختار DOM است. از طریق این شیء، جاوا اسکریپت می‌تواند متدهای مختلف DOM را فراخوانی کرده و به عناصر خاصی دسترسی پیدا کند. به عنوان مثال، جاوا اسکریپت می‌تواند با استفاده از document.getElementById(“myElement”) به یک عنصر خاص در صفحه دسترسی یابد و سپس با myElement.textContent = “New Text” محتوای متنی آن را تغییر دهد. این ارتباط پویا، امکان واکنش به اقدامات کاربر، به‌روزرسانی محتوا در لحظه و تغییرات بصری را بدون نیاز به بارگذاری مجدد صفحه فراهم می‌کند.

مزایای استفاده از DOM در جاوا اسکریپت: چرا یادگیری آن حیاتی است؟

یادگیری معرفی DOM و کاربرد آن در JavaScript، یک مهارت اساسی برای هر توسعه‌دهنده فرانت‌اند است. مزایای آن فراتر از صرفاً تغییر محتواست و پایه‌های وب مدرن را شکل می‌دهد:

  • ایجاد صفحات وب پویا و تعاملی: مهم‌ترین مزیت DOM، توانایی آن در ایجاد صفحات وبی است که به ورودی کاربر واکنش نشان می‌دهند، بدون اینکه نیاز به بارگذاری مجدد صفحه باشد. این شامل فرم‌های پویا، منوهای کشویی، گالری‌های تصاویر و انیمیشن‌های CSS می‌شود.
  • واکنش به رویدادهای کاربر: با DOM، جاوا اسکریپت می‌تواند به رویدادهای مختلفی مانند کلیک ماوس، حرکت نشانگر ماوس، فشردن کلیدهای کیبورد یا ارسال فرم‌ها پاسخ دهد. این قابلیت، پایه‌ای برای توسعه برنامه‌های وب کاربردی است.
  • به‌روزرسانی محتوا در لحظه: DOM امکان به‌روزرسانی بخش‌های خاصی از صفحه وب را بدون تأثیر بر کل صفحه فراهم می‌کند. این برای نمایش داده‌های لحظه‌ای، اعلان‌ها یا نتایج جستجو بسیار کاربردی است و تجربه کاربری را بهبود می‌بخشد.
  • شخصی‌سازی رابط کاربری: وب‌سایت‌ها و برنامه‌ها می‌توانند بر اساس ترجیحات کاربر، محتوا و چیدمان خود را تغییر دهند که این امر به لطف قابلیت‌های دستکاری DOM امکان‌پذیر است.
  • ساخت برنامه‌های تک صفحه‌ای (Single Page Applications – SPAs): فریمورک‌های مدرن جاوا اسکریپت مانند React، Vue و Angular که ستون فقرات SPAs هستند، به شدت به DOM برای رندرینگ و مدیریت تعاملات متکی هستند. درک DOM برای کار با این فریمورک‌ها ضروری است.

دسترسی و انتخاب عناصر در DOM: هدف‌گیری دقیق برای تغییر

برای اینکه جاوا اسکریپت بتواند عناصر HTML را دستکاری کند، ابتدا باید بتواند آن‌ها را انتخاب یا “هدف‌گیری” کند. DOM مجموعه‌ای از متدهای قدرتمند را برای انتخاب عناصر فراهم می‌کند. این متدها بسته به نوع شناساگر (ID، کلاس، تگ) یا پیچیدگی انتخابگرهای CSS، متفاوت هستند.

انتخاب عناصر با استفاده از شناسه (ID)

متد document.getElementById(id) یکی از پرکاربردترین و کارآمدترین متدهای انتخاب عناصر است. هر ID در یک سند HTML باید منحصر به فرد باشد، بنابراین این متد دقیقاً یک عنصر را برمی‌گرداند. این روش برای دسترسی سریع به یک عنصر خاص زمانی که ID آن مشخص است، ایده‌آل است.

این یک پاراگراف است.

// JavaScript const paragraph = document.getElementById(“myParagraph”);

انتخاب عناصر با استفاده از نام برچسب (TagName) و نام کلاس (ClassName)

متد document.getElementsByTagName(tagname) تمام عناصر HTML با نام تگ مشخص (مانند 

 یا 

) را برمی‌گرداند. این متد یک HTMLCollection زنده (Live) از عناصر را بازمی‌گرداند.

عنصر اول
عنصر دوم

// JavaScript const divs = document.getElementsByTagName(“div”); // یک HTMLCollection

متد document.getElementsByClassName(classname) تمام عناصر با نام کلاس مشخص را برمی‌گرداند و مانند getElementsByTagName، یک HTMLCollection زنده بازمی‌گرداند.

متن مهم // JavaScript const highlights = document.getElementsByClassName(“highlight”); // یک HTMLCollection

انتخاب پیشرفته با CSS Selectorها

متدهای document.querySelector(selector) و document.querySelectorAll(selector) امکان انتخاب عناصر را با استفاده از قدرت انتخابگرهای CSS فراهم می‌کنند. querySelector اولین عنصری را که با انتخابگر منطبق است برمی‌گرداند، در حالی که querySelectorAll تمام عناصر منطبق را در قالب یک NodeList ایستا (Static) بازمی‌گرداند.

  • آیتم ۱
  • آیتم ۲

// JavaScript const firstItem = document.querySelector(“.item”); // فقط آیتم اول const allItems = document.querySelectorAll(“.item”); // NodeList از هر دو آیتم

تفاوت بین HTMLCollection و NodeList

یکی از نکات مهم در انتخاب عناصر DOM، درک تفاوت HTMLCollection و NodeList است. HTMLCollection یک مجموعه زنده از عناصر است؛ به این معنی که اگر عناصر جدیدی به DOM اضافه یا از آن حذف شوند، این مجموعه به طور خودکار به‌روزرسانی می‌شود. در مقابل، NodeList که توسط querySelectorAll بازگردانده می‌شود، یک مجموعه ایستا است و پس از ایجاد، تغییرات بعدی در DOM بر روی آن تأثیری ندارند. این تفاوت در سناریوهایی که نیاز به دستکاری دینامیک عناصر داریم، بسیار مهم است و می‌تواند بر عملکرد و رفتار کد جاوا اسکریپت ما تأثیر بگذارد.

دستکاری محتوا، ویژگی‌ها و استایل عناصر HTML با DOM

پس از انتخاب عناصر DOM، گام بعدی دستکاری آن‌هاست. HTML DOM ابزارهای قدرتمندی را برای تغییر محتوا، ویژگی‌ها و استایل‌های CSS فراهم می‌کند که به توسعه‌دهندگان اجازه می‌دهد صفحات وب کاملاً پویا ایجاد کنند.

تغییر محتوای متنی و HTML

برای تغییر محتوای HTML با جاوا اسکریپت، دو ویژگی اصلی وجود دارد: innerHTML و textContent.

  • element.innerHTML: این ویژگی به شما امکان می‌دهد محتوای HTML (شامل تگ‌ها) یک عنصر را دریافت یا تنظیم کنید. استفاده از آن برای افزودن یا تغییر ساختارهای HTML کامل در داخل یک عنصر بسیار کاربردی است.

    متن قدیمی

    // JavaScript document.getElementById(“container”).innerHTML = ”

    عنوان جدید

    محتوای جدید.

    “;

  • element.textContent: این ویژگی برای دریافت یا تنظیم محتوای متنی خالص یک عنصر استفاده می‌شود. برخلاف innerHTML، هر HTML که به آن اختصاص دهید، به عنوان متن ساده تفسیر می‌شود و از مشکلات امنیتی احتمالی جلوگیری می‌کند.
    اطلاعات

    // JavaScript document.getElementById(“info”).textContent = “این فقط متن است، نه HTML.”;

تفاوت کلیدی این دو در این است که innerHTML HTML را تفسیر می‌کند، در حالی که textContent آن را به عنوان متن ساده در نظر می‌گیرد و از نظر امنیتی برای جلوگیری از حملات XSS (Cross-Site Scripting) در مواقعی که ورودی کاربر را نمایش می‌دهید، textContent ارجحیت دارد.

تغییر ویژگی‌ها (Attributes) عناصر

خصوصیات DOM به شما امکان می‌دهند به ویژگی‌های HTML عناصر (مانند src برای تصاویر یا href برای لینک‌ها) دسترسی یافته و آن‌ها را تغییر دهید.

  • element.setAttribute(attributeName, value): این متد برای افزودن یک ویژگی جدید یا تغییر مقدار یک ویژگی موجود استفاده می‌شود. تصویر قدیمی // JavaScript document.getElementById(“myImage”).setAttribute(“src”, “new.jpg”);
  • element.getAttribute(attributeName): برای دریافت مقدار یک ویژگی مشخص استفاده می‌شود.
  • element.removeAttribute(attributeName): برای حذف یک ویژگی از عنصر.

تغییر استایل (CSS) عناصر

element.style.propertyName = “value”: این روش به شما اجازه می‌دهد استایل‌های CSS درون‌خطی یک عنصر را مستقیماً از طریق جاوا اسکریپت تغییر دهید. هر ویژگی CSS با نگارش camelCase در شیء style قابل دسترسی است (مثلاً backgroundColor به جای background-color).

عنوان مقاله

// JavaScript document.getElementById(“myTitle”).style.color = “red”; document.getElementById(“myTitle”).style.fontSize = “24px”;

افزودن، حذف و جابجایی عناصر در DOM: ساختاردهی پویا وب

قابلیت افزودن و حذف عناصر DOM به توسعه‌دهندگان اجازه می‌دهد تا ساختار صفحه را به‌صورت پویا تغییر دهند، که برای ایجاد محتوای سفارشی، بارگذاری تنبل (Lazy Loading) و ساخت برنامه‌های پیچیده ضروری است.

ایجاد عناصر جدید

  • document.createElement(tagName): برای ایجاد یک گره عنصر جدید با نام تگ مشخص (مانند ‘div’، ‘p’، ‘span’). این متد فقط گره را می‌سازد و هنوز آن را به درخت DOM اضافه نمی‌کند.
  • document.createTextNode(text): برای ایجاد یک گره متنی جدید. این گره معمولاً به عنوان فرزند یک عنصر دیگر اضافه می‌شود.

// JavaScript const newDiv = document.createElement(“div”); const textNode = document.createTextNode(“این یک متن جدید است.”); newDiv.appendChild(textNode);

افزودن عناصر به درخت DOM

  • parentNode.appendChild(childNode): این متد یک گره را به عنوان آخرین فرزند به یک گره والد مشخص اضافه می‌کند.
  • parentNode.insertBefore(newNode, referenceNode): این متد یک گره جدید را قبل از یک گره فرزند مرجع موجود به عنوان فرزند parentNode اضافه می‌کند.

// JavaScript const parentElement = document.getElementById(“parent”); const newParagraph = document.createElement(“p”); newParagraph.textContent = “پاراگراف تازه اضافه شده.”; parentElement.appendChild(newParagraph);

حذف عناصر از DOM

  • parentNode.removeChild(childNode): این متد یک گره فرزند مشخص را از گره والدش حذف می‌کند.
  • element.remove(): یک روش مدرن‌تر و ساده‌تر برای حذف یک عنصر از DOM است که نیاز به ارجاع به والد ندارد.

// JavaScript const elementToRemove = document.getElementById(“item-to-remove”); elementToRemove.remove(); // یا parentNode.removeChild(elementToRemove);

جایگزینی عناصر در DOM

parentNode.replaceChild(newChild, oldChild): این متد یک گره فرزند موجود (oldChild) را با یک گره جدید (newChild) در درخت DOM جایگزین می‌کند. گره oldChild پس از این عملیات دیگر در DOM وجود نخواهد داشت.

// JavaScript const oldElement = document.getElementById(“old-one”); const newElement = document.createElement(“span”); newElement.textContent = “جایگزین شد!”; oldElement.parentNode.replaceChild(newElement, oldElement);

کار با رویدادها (Events) در DOM: تعامل فعال با کاربر

رویدادها (Events) در DOM سازوکاری هستند که از طریق آن جاوا اسکریپت می‌تواند به اقدامات کاربر یا تغییرات مرورگر واکنش نشان دهد. Event Handling (مدیریت رویدادها) یکی از جنبه‌های اصلی ایجاد صفحات وب تعاملی است.

مقدمه‌ای بر رویدادها

انواع مختلفی از رویدادها وجود دارند که می‌توانند در DOM رخ دهند:

  • رویدادهای ماوس: مانند click (کلیک کردن)، mouseover (حرکت ماوس روی عنصر)، mouseout (حرکت ماوس از روی عنصر)، mousedown، mouseup و dblclick.
  • رویدادهای کیبورد: مانند keydown (فشردن کلید)، keyup (رها کردن کلید) و keypress (فشردن و نگه داشتن کلید).
  • رویدادهای فرم: مانند submit (ارسال فرم)، change (تغییر مقدار ورودی)، focus (تمرکز روی ورودی) و blur (از دست دادن تمرکز).
  • رویدادهای پنجره: مانند load (بارگذاری کامل صفحه)، resize (تغییر اندازه پنجره) و scroll (اسکرول کردن صفحه).

element.addEventListener(event, handlerFunction): روش مدرن مدیریت رویدادها

متد addEventListener() روش توصیه شده و مدرن برای پیوست کردن توابع کنترل‌کننده رویداد به عناصر است. این متد سه پارامتر اصلی می‌گیرد: نام رویداد (مثلاً ‘click’)، تابع کنترل‌کننده رویداد و یک شیء اختیاری برای تنظیم گزینه‌ها (مانند capture یا once).

کلیک کنید // JavaScript const button = document.getElementById(“myButton”); button.addEventListener(“click”, function() { alert(“دکمه کلیک شد!”); });

این متد امکان پیوست کردن چندین کنترل‌کننده رویداد به یک رویداد خاص در یک عنصر را فراهم می‌کند و از مشکلات روش‌های قدیمی مانند onclick که فقط یک تابع را می‌پذیرفت، جلوگیری می‌کند. همچنین، تابع removeEventListener() برای حذف کنترل‌کننده‌های رویداد استفاده می‌شود.

Event Object

هنگامی که یک رویداد رخ می‌دهد، مرورگر یک شیء رویداد (Event Object) را به تابع کنترل‌کننده ارسال می‌کند. این شیء حاوی اطلاعات مفیدی در مورد رویداد است، مانند event.target (عنصری که رویداد را آغاز کرده است)، event.type (نوع رویداد) و event.preventDefault() (برای متوقف کردن رفتار پیش‌فرض مرورگر، مثلاً جلوگیری از ارسال فرم).

پیمایش (Traversal) درخت DOM: گشت و گذار در ساختار سند

پیمایش (Traversal) درخت DOM به معنای حرکت در ساختار درختی یک سند HTML برای دسترسی به گره‌های مختلف (والد، فرزند، خواهر و برادر) است. این قابلیت زمانی مفید است که شما یک گره خاص را در اختیار دارید و می‌خواهید به گره‌های مرتبط با آن دسترسی پیدا کنید، بدون اینکه نیاز به انتخاب مجدد از طریق متدهای querySelector یا getElementById باشد.

روابط بین گره‌ها در درخت DOM

درخت DOM بر اساس روابط والد-فرزندی و خواهر-برادری سازماندهی شده است:

  • والد (Parent): گره‌ای که یک یا چند گره فرزند دارد.
  • فرزند (Child): گره‌ای که مستقیماً زیر یک گره والد قرار دارد.
  • خواهر/برادر (Sibling): گره‌هایی که یک والد مشترک دارند.

خصوصیات مهم برای پیمایش

جاوا اسکریپت مجموعه‌ای از خصوصیات را برای پیمایش DOM فراهم می‌کند:

  • parentNode: والد مستقیم یک گره را برمی‌گرداند.
  • childNodes: یک NodeList از تمام گره‌های فرزند (شامل گره‌های متنی و کامنت) را برمی‌گرداند.
  • children: یک HTMLCollection از گره‌های فرزند از نوع عنصر را برمی‌گرداند (گره‌های متنی و کامنت را شامل نمی‌شود).
  • firstChild / firstElementChild: اولین گره فرزند (یا اولین گره عنصر فرزند) را برمی‌گرداند.
  • lastChild / lastElementChild: آخرین گره فرزند (یا آخرین گره عنصر فرزند) را برمی‌گرداند.
  • nextSibling / nextElementSibling: گره خواهر/برادر بعدی (یا گره عنصر خواهر/برادر بعدی) را برمی‌گرداند.
  • previousSibling / previousElementSibling: گره خواهر/برادر قبلی (یا گره عنصر خواهر/برادر قبلی) را برمی‌گرداند.

متن ۱

متن ۲

// JavaScript const spanElement = document.querySelector(“#parent span”); const parent = spanElement.parentNode; // div#parent const nextSibling = spanElement.nextElementSibling; // null (چون عنصر دیگری نیست)

این خصوصیات به توسعه‌دهندگان انعطاف‌پذیری زیادی برای دسترسی و تغییر عناصر در هر نقطه‌ای از درخت DOM می‌دهند.

انواع داده‌ها و رابط‌های اصلی DOM: نگاهی عمیق‌تر

درک انواع داده‌های اصلی DOM برای کارایی و دقت در دستکاری سند وب حیاتی است. DOM بر اساس مجموعه‌ای از رابط‌ها (Interfaces) تعریف شده است که هر یک رفتار و خصوصیات خاصی را برای انواع مختلف گره‌ها در درخت DOM مشخص می‌کنند.

Document Object

شیء Document نمایانگر کل صفحه وب است و نقطه ورود اصلی به DOM محسوب می‌شود. از طریق این شیء می‌توان به ویژگی‌هایی مانند document.body (عنصر  document.head (عنصر  document.title و متدهای مختلفی مانند createElement یا getElementById دسترسی پیدا کرد.

Node Object و Element Object

Node Object پایه و اساس تمام گره‌ها در DOM است و خصوصیات و متدهای مشترکی (مانند parentNode یا appendChild) را برای همه انواع گره‌ها (عنصر، متن، کامنت) فراهم می‌کند.

Element Object نوع خاصی از Node است که نمایانگر تگ‌های HTML (مانند 

، 

) است. این شیء علاوه بر خصوصیات Node، متدها و خصوصیات مخصوص به خود (مانند innerHTML، setAttribute و style) را نیز دارد.

Attr Object

این شیء نمایانگر ویژگی‌های HTML (مانند id، class، src) است. هرچند معمولاً توسعه‌دهندگان مستقیماً با Attr Object کار نمی‌کنند و از متدهای setAttribute و getAttribute روی Element Object استفاده می‌کنند.

خصوصیات مهم شیء document

شیء document مجموعه‌ای از خصوصیات مهم را ارائه می‌دهد که دسترسی سریع به بخش‌های کلیدی سند را فراهم می‌کند:

خاصیت توضیح
document.body عنصر سند را برمی‌گرداند.
document.head عنصر سند را برمی‌گرداند.
document.title عنوان سند (محتوای تگ

دکمه بازگشت به بالا