22- آموزش جاوااسکریپت | پیمایش DOM: حرکت بین والد، فرزند و همسایه (Traversing the DOM)
در این آموزش با مفهوم پیمایش یا Traversing در DOM آشنا میشویم. یاد میگیریم چگونه بعد از انتخاب یک عنصر، به سمت بالا (والد)، پایین (فرزندان) یا طرفین (همسایهها) حرکت کنیم. همچنین تفاوت بین گرههای متنی (Text Nodes) و عناصر HTML را بررسی کرده و یاد میگیریم چگونه فقط عناصر واقعی را هدف قرار دهیم.
HTML استفاده شده در این پست همان HTML پست 19 است یک ul با کلاس collection داریم که شامل چند li با کلاس collection-item است و داخل هر آیتم نیز یک لینک قرار گرفته است
در بخشهای قبلی با نحوه انتخاب عناصر آشنا شدیم. حالا قصد داریم یاد بگیریم چگونه در درخت DOM پیمایش کنیم. پیمایش یا Traversing به معنای حرکت در ساختار درختی DOM است؛ یعنی جابهجا شدن بین والدها، فرزندان و همسایههای یک عنصر.
برای شروع، یک ساختار پایه برای لاگ گرفتن در نظر میگیریم. یعنی یک متغیر تعریف میکنیم و در انتهای اسکریپت لاگ آن را نشان میدهیم، یک لیست (<ul>) با کلاس collection داریم:
let val;
const list = document.querySelector('ul.collection');
const listItem = document.querySelector('li.collection-item:first-child');
val = listItem;
val = list;
console.log(val);
۱. حرکت به سمت پایین (فرزندان)
الف) childNodes
این ویژگی لیستی از تمام گرههای فرزند را برمیگرداند. نکته مهم این است که این لیست شامل «گرههای متنی» (Text Nodes) نیز میشود که همان شکستن خط (Line Break) در کد HTML هستند.
val = list.childNodes;
در خروجی این کد، علاوه بر تگهای <li> مورد انتظار، گرههایی به نام text هم میبینید. اینها همان فضاهای خالی یا اینترهایی هستند که در فایل HTML بین تگها زدهاید.
ب) children
در اکثر مواقع ما فقط به دنبال عناصر HTML هستیم و گرههای متنی برایمان اهمیتی ندارند. در این صورت از ویژگی children استفاده میکنیم که یک HTMLCollection شامل فقط عناصر (Elements) برمیگرداند.
val = list.children; // فقط تگهای li را برمیگرداند
val = list.children[1]; // دسترسی به دومین فرزند
list.children[1].textContent = 'سلام دنیا'; // تغییر متن دومین فرزند
ج) شناسایی نوع گره (Node Type)
هر گره در DOM یک عدد به عنوان nodeType دارد. برخی از مهمترین آنها عبارتند از:
- 1: عنصر (Element)
- 2: ویژگی (Attribute) - منسوخ شده
- 3: گره متنی (Text node)
- 8: کامنت (Comment)
- 9: خودِ سند (Document)
- 10: نوع سند (Doctype)
val = list.childNodes[0].nodeType; // اگر متن باشد، عدد 3 را برمیگرداند
د) دسترسی به فرزندانِ فرزندان
شما میتوانید این ویژگیها را به صورت زنجیرهای استفاده کنید:
// دسترسی به لینک داخل چهارمین آیتم لیست و تغییر ID آن
val = list.children[3].children[0];
list.children[3].children[0].id = 'test-link';
هـ) اولین و آخرین فرزند
برای دسترسی سریع به ابتدا و انتهای لیست فرزندان از متدهای زیر استفاده میشود:
firstChildوlastChild: اولین و آخرین گره (ممکن است گره متنی باشد).firstElementChildوlastElementChild: اولین و آخرین عنصر واقعی HTML.
val = list.firstElementChild; // اولین li
val = list.lastElementChild; // آخرین li
val = list.childElementCount; // تعداد فرزندان (در اینجا عدد 5)
۲. حرکت به سمت بالا (والد)
برای دسترسی به والد یک عنصر، از ویژگیهای parentNode یا parentElement استفاده میکنیم. در اکثر موارد این دو نتیجه یکسانی دارند.
val = listItem.parentNode; // گرفتن تگ ul
val = listItem.parentElement; // باز هم تگ ul
// حرکت به چند سطح بالاتر (والدِ والد)
val = listItem.parentElement.parentElement; // رفتن به div که لیست در آن قرار دارد
۳. حرکت به سمت طرفین (همسایهها)
همسایهها (Siblings) عناصری هستند که والد یکسانی دارند.
الف) همسایه بعدی
nextSibling: گره بعدی (ممکن است متن باشد).nextElementSibling: عنصر HTML بعدی.
val = listItem.nextElementSibling; // رفتن به دومین li
val = listItem.nextElementSibling.nextElementSibling; // رفتن به سومین li
ب) همسایه قبلی
previousSibling: گره قبلی.previousElementSibling: عنصر HTML قبلی.
val = listItem.previousElementSibling; // چون اولین آیتم است، خروجی null خواهد بود
جمعبندی
پیمایش DOM به ما این قدرت را میدهد که با داشتن یک نقطه شروع در صفحه، به هر عنصر دیگری در بالا، پایین یا اطراف آن دسترسی پیدا کنیم. تفاوت اصلی که همیشه باید به یاد داشته باشید، تفاوت بین ویژگیهایی است که کلمه Element را در نام خود دارند (مانند children یا nextElementSibling) با آنهایی که ندارند؛ دسته اول فقط با تگهای HTML کار میکنند و دسته دوم شامل فضاهای خالی و متون نیز میشوند.
در بخشهای بعدی، به سراغ نحوه ایجاد و حذف عناصر در DOM خواهیم رفت.