حرکت بین گرههای DOM: پیمایش (Traversing)
مقدمه
در درس قبل، روشهای مختلف انتخاب مستقیم یک عنصر را دیدیم. اما گاهی بهجای انتخاب مستقیم، لازم است از یک عنصری که در دست داریم، به عنصر مرتبط دیگری در DOM Tree حرکت کنیم؛ مثلاً از یک فرزند به والدش برسیم، یا بین خواهر و برادرها جابهجا شویم. به این کار، Traversing DOM (پیمایش DOM) میگویند؛ و دقیقاً بر پایهی همان ساختار درختی است که در درس اول همین فصل دیدیم.
دسترسی به فرزندان یک عنصر
برای مثال این ساختار HTML را در نظر بگیرید:
<div id="container">
<p>پاراگراف اول</p>
<p>پاراگراف دوم</p>
</div>
تحلیل کد
children یک HTMLCollection (که در درس قبل دیدیم) شامل فقط فرزندانی است که خودشان یک Element هستند (یعنی تگها، نه متن یا فاصلههای خالی بین تگها). firstElementChild و lastElementChild بهترتیب اولین و آخرین فرزند از نوع Element را مستقیماً برمیگردانند؛ بدون نیاز به نوشتن children[0].
تفاوت مهم: Element در برابر Node
جاوااسکریپت بین Element (خودِ تگهای HTML) و Node (هر چیزی در DOM Tree، از جمله متن و فاصلههای خالی) تمایز قائل میشود. اگر بهجای children از childNodes استفاده کنیم، نتیجهی متفاوتی میگیریم:
تحلیل رفتار جاوااسکریپت
children.length معمولاً همان تعداد تگهای فرزند (در مثال بالا، دو p) را نشان میدهد. اما childNodes.length عددی بزرگتر برمیگرداند؛ چون فضای خالی و خطوط جدید بین تگها در کد HTML (که هنگام قالببندی خوانا نوشتن کد، طبیعی است) نیز بهعنوان Node های متنی مستقل شمرده میشوند. به همین دلیل، در اکثر سناریوهای عملی که فقط با تگها سروکار داریم، children و مشتقات آن (مثل firstElementChild) گزینهی مناسبتری نسبت به childNodes و firstChild هستند.
دسترسی به والد یک عنصر
برای حرکت از یک عنصر به سمت والد آن، از parentElement استفاده میکنیم:
دسترسی به خواهر و برادرها (Siblings)
برای جابهجایی بین عناصر همسطح (یعنی عناصری که والد یکسانی دارند)، از nextElementSibling و previousElementSibling استفاده میکنیم:
تحلیل کد
در این مثال، firstP اولین p است. با firstP.nextElementSibling، به دومین p که خواهر بلافصل آن است میرسیم. سپس با secondP.previousElementSibling، دوباره به همان p اول برمیگردیم؛ این نشان میدهد که این دو متد، دقیقاً معکوس یکدیگر عمل میکنند و امکان حرکت در هر دو جهت بین عناصر همسطح را فراهم میکنند. اگر عنصری آخرین یا اولین فرزند والد خودش باشد، این متدها بهترتیب null برمیگردانند؛ نکتهای که باید در کدنویسی واقعی همیشه در نظر گرفته شود، همانطور که در درس قبل دربارهی خطرات نادیده گرفتن null دیدیم.
ترکیب Traversing با Selecting
در عمل، اغلب Traversing و Selecting با یکدیگر ترکیب میشوند؛ برای نمونه، پیدا کردن یک عنصر خاص و سپس حرکت نسبت به آن:
let button = document.querySelector(".submit-btn");
let form = button.parentElement;
let firstInput = form.querySelector("input");
در این مثال، ابتدا دکمه با querySelector انتخاب شده، سپس با parentElement به فرم اطراف آن رسیدهایم، و در نهایت با یک querySelector دیگر (اینبار روی خودِ form، نه document)، اولین ورودی داخل آن فرم را پیدا کردهایم. این نشان میدهد که متدهای Selecting که در درس قبل دیدیم، نه فقط روی document، بلکه روی هر عنصر دیگری هم قابل فراخوانی هستند؛ در این حالت، جستوجو فقط در میان فرزندان همان عنصر خاص انجام میشود، نه کل صفحه.
جدول جمعبندی
| متد/Property | هدف |
|---|---|
| children / firstElementChild / lastElementChild | دسترسی به فرزندان (فقط Element) |
| childNodes / firstChild / lastChild | دسترسی به تمام Node ها (شامل متن و فاصله) |
| parentElement | دسترسی به والد |
| nextElementSibling / previousElementSibling | حرکت بین عناصر همسطح |
جمعبندی
پیمایش DOM به ما اجازه میدهد از یک عنصر مشخص، نسبت به عناصر مرتبط آن در ساختار درختی حرکت کنیم: به سمت فرزندان با children، به سمت والد با parentElement، و بین خواهر و برادرها با nextElementSibling و previousElementSibling. نسخههای مبتنی بر Element (مثل children) معمولاً ترجیح داده میشوند، چون برخلاف نسخههای مبتنی بر Node (مثل childNodes)، شامل متنهای خالی و فاصلهها نمیشوند.
