مقدمه
در فصل قبل، هستهی اصلی کار با DOM را یاد گرفتیم. در این فصل، به بررسی «اکستنشنهای DOM»
میپردازیم؛ این اکستنشنها مجموعهای از APIها و پراپرتیهای پیشرفتهتر هستند که قابلیتهای جدیدی
را به DOM اضافه کرده و یا روشهای بهینهتر و سادهتری برای انجام کارهای رایج فراهم میکنند. در
اولین درس از این فصل، به دو موضوع کلیدی میپردازیم: روشهای استاندارد برای دستکاری استایلهای
CSS یک عنصر و تکنیکهای پیمایش مدرن و کارآمد در درخت DOM.
کار با استایلهای عناصر
بهترین روش برای تغییر ظاهر عناصر، تغییر کلاسهای CSS آنها از طریق classList است. اما
گاهی نیاز داریم مقادیر استایل خاصی را به صورت پویا و مستقیم از طریق جاوااسکریپت تنظیم کنیم. برای
این کار، DOM دو ابزار اصلی در اختیار ما قرار میدهد.
پراپرتی style
هر عنصر HTML یک پراپرتی به نام style دارد که به ما امکان دسترسی به استایلهای درونخطی (inline
styles) آن عنصر را میدهد. این پراپرتی خود یک شیء است که پراپرتیهای CSS را به فرمت camelCase در
خود دارد (برای مثال، background-color در CSS به backgroundColor در جاوااسکریپت
تبدیل میشود).
JAVASCRIPT
const box = document.getElementById('myBox');
box.style.width = '200px';
box.style.height = '100px';
box.style.backgroundColor = 'tomato';
box.style.borderLeft = '5px solid black';
این کد به صورت مستقیم مقادیر استایل را به اتریبیوت style عنصر اضافه میکند. این استایلها
به دلیل ماهیت خطی بودن، بالاترین اولویت را دارند و استایلهای تعریف شده در فایلهای CSS خارجی را
لغو میکنند (مگر اینکه آن استایلها دارای `!important` باشند).
خواندن استایلهای محاسبهشده
یک محدودیت بزرگ پراپرتی style این است که فقط میتواند استایلهایی را بخواند که به صورت
خطی (inline) روی خود عنصر تنظیم شده باشند. این پراپرتی نمیتواند به استایلهایی که از طریق
استایلشیتهای خارجی (external) یا داخلی (internal) به عنصر اعمال شدهاند، دسترسی داشته باشد.
برای خواندن مقدار نهایی و محاسبهشدهی یک پراپرتی CSS روی یک عنصر، باید از تابع سراسری getComputedStyle() استفاده کنیم. این تابع عنصر مورد نظر را به عنوان
آرگومان گرفته و یک شیء فقط-خواندنی برمیگرداند که حاوی تمام مقادیر CSS نهایی آن عنصر است.
JAVASCRIPT
const box = document.getElementById('myBox');
const styles = window.getComputedStyle(box);
console.log(styles.backgroundColor);
console.log(styles.padding);
console.log(styles.fontFamily);
همانطور که میبینید، getComputedStyle() هم استایل خطی
(backgroundColor) و هم استایلهای اعمال شده از فایل CSS (padding و
fontFamily) را به درستی میخواند.
پیمایش بهینه درخت (Element Traversal)
همانطور که در فصل قبل دیدیم، پراپرتیهای پیمایشی مانند childNodes و firstChild
تمام انواع گره، از جمله گرههای متنی (فضاهای خالی) و کامنتها را برمیگردانند. این رفتار اغلب
منجر به کدهای پیچیدهتر برای فیلتر کردن گرههای غیرعنصری میشود. اکستنشن Element
Traversal مجموعهای از پراپرتیهای جایگزین را فراهم میکند که فقط روی گرههای عنصر تمرکز
دارند.
- children: یک HTMLCollection زنده از فرزندان عنصر یک گره.
- firstElementChild / lastElementChild: اولین و آخرین فرزند عنصر.
- nextElementSibling / previousElementSibling: خواهر و برادر عنصر بعدی و
قبلی.
- childElementCount: تعداد فرزندان عنصر.
JAVASCRIPT
const parent = document.getElementById('parent');
console.log(parent.childNodes.length);
console.log(parent.children.length);
console.log(parent.firstChild.nodeName);
console.log(parent.firstElementChild.tagName);
این مثال به وضوح نشان میدهد که چگونه پراپرتیهای Element Traversal (مانند
children و firstElementChild) با نادیده گرفتن گرههای متنی و کامنت، کد پیمایشی ما
را بسیار تمیزتر و قابل پیشبینیتر میکنند.
پیدا کردن نزدیکترین والد با closest
یکی دیگر از متدهای پیمایشی بسیار مفید، closest() است. این متد که
روی یک عنصر فراخوانی میشود، یک سلکتور CSS میگیرد و درخت DOM را به سمت بالا
(از خود عنصر شروع به سمت والدین) پیمایش میکند. اولین عنصری که با سلکتور مطابقت داشته باشد
را برمیگرداند. اگر هیچ والد منطبقی پیدا نشود، null برمیگرداند.
JAVASCRIPT
const startNode = document.getElementById('start');
const container = startNode.closest('div.container');
const article = startNode.closest('article');
console.log(container.className);
console.log(article.tagName);
متد closest() برای پیدا کردن والد یا ظرف نگهدارندهی یک عنصر، به
ویژه در مدیریت رویدادها (event handling)، فوقالعاده کاربردی است و ما را از نوشتن حلقههای
پیمایشی با parentNode بینیاز میکند.
در این درس روشهای پیشرفتهتری برای کار با استایلها و پیمایش DOM را بررسی کردیم. یاد گرفتیم که
چگونه با پراپرتی style و تابع getComputedStyle() استایلها
را مدیریت کنیم و چگونه با استفاده از پراپرتیهای پیمایش عنصر و متد closest() به شکلی بهینهتر و خواناتر در درخت DOM حرکت کنیم. در درس
بعدی، به سراغ یکی از مفاهیم قدرتمند اما کمتر شناختهشدهی DOM یعنی `Ranges` خواهیم رفت و یاد
میگیریم که چگونه بخشهایی از یک سند را به صورت برنامهنویسی انتخاب کرده و دستکاری کنیم، مشابه
کاری که کاربر با ماوس انجام میدهد.