البرمجة

نموذج DOM في جافاسكريبت

جدول المحتوى

نموذج كائن المستند (DOM) في جافاسكريبت: البنية، الآليات، وأفضل الممارسات الحديثة لتحسين أداء تطبيقات الويب

مقدمة عامة

يُعَدُّ نموذج كائن المستند — المعروف اختصارًا بـ DOM — أحد الركائز التقنية الأساسية التي يقوم عليها تطوير الواجهات التفاعلية للويب. فمن خلاله يتمكّن المطوّر من تمثيل صفحة HTML أو XML على هيئة شجرة كائنات قابلة للبرمجة، ما يسمح بالتعديل اللحظي على عناصر الصفحة وإنشاء تجارب مستخدم ديناميكية. يلقي هذا المقال الموسّع الضوء على الجوانب النظرية والعملية لنموذج كائن المستند، ابتداءً من جذوره التاريخية وتعريفه الرسمي، مرورًا بآلية عمله التفصيلية في المتصفّحات الحديثة، وصولًا إلى استراتيجيات الأداء المتقدمة وأفضل الممارسات لضمان شفرة نظيفة وقابلة للصيانة.


1. الجذور التاريخية وتطور المواصفات القياسية

1.1 بدايات الويب الساكن

عند انطلاق شبكة الويب العالمية في مطلع التسعينيات، كانت صفحات HTML وثائق ثابتة؛ إذ لم يكن ثمة وسيلة معيارية لتعديل بنية المستند بعد تحميله. ظهرت الحاجة لاحقًا إلى تحديث المحتوى دون إعادة تحميل الصفحة بالكامل، لتأتي لغة JavaScript سنة 1995 وتطرح مفهوم التلاعب بالشجرة المنطقية للمستند من جانب العميل.

1.2 من DOM المستوى 0 إلى DOM المستوى 4

  • DOM المستوى 0 (1996): واجهة غير رسمية متواضعة أتاحت الوصول إلى بعض خصائص النوافذ والنماذج.

  • DOM المستوى 1 (1998): أول مواصفة صادرة عن W3C قدَّمت هيكلية شجرة العقد (Node Tree).

  • DOM المستوى 2 (2000): أضاف أحداثًا قياسية، وأنماط CSS، ودعم XMLNames.

  • DOM المستوى 3 (2004): حسّن دعم الترميز الموحد (Unicode) ومعالجة الأخطاء.

  • DOM المستوى 4 (2015): دمج المواصفات السابقة وركّز على التوافقية مع HTML5 وواجهات برمجة التطبيقات الحديثة.


2. البنية الجوهرية لشجرة DOM

2.1 العقد (Nodes) وأنواعها الأساسية

يتكوّن المستند من مجموعة عقد مرتبطة بعلاقات أب–ابن وأخ–أخ حسب الهيكل الآتي:

نوع العقدة الواجهة البرمجية الوصف الوظيفي مثال نموذجي
Document Document جذر الشجرة والمسؤول عن إنشاء العناصر document.documentElement
Element HTMLElement تمثيل عناصر HTML

,

Text Text محتوى نصي خام نص داخل فقرة
Comment Comment تعليقات ملاحظات غير مرئية
DocumentFragment DocumentFragment حاوية مؤقتة خفيفة بناء أجزاء دون إعادة رسم

2.2 الخصائص والعلاقات

  • parentNode: للوصول إلى العقدة الأب.

  • childNodes: قائمة بالعقد الأبناء.

  • firstChild / lastChild: تسريع الوصول لأطراف الأبناء.

  • nextSibling / previousSibling: التنقّل أفقيًا بين الإخوة.

  • nodeType: رقم نوع العقدة (1 للعناصر، 3 للنص…).


3. واجهات برمجة التطبيقات الأساسية للتلاعب بالـDOM

3.1 إنشاء العناصر وإضافتها

javascript
const parag = document.createElement('p'); parag.textContent = 'مرحبا بالعالم'; document.body.appendChild(parag);
  • createElement() يُنشئ عنصرًا دون إدراجه.

  • appendChild() يُدرج العقدة في نهاية الأب.

3.2 استعلام الشجرة

  • getElementById(): أسرع معرّف فريد.

  • querySelector()/querySelectorAll(): صيغ CSS انتقائية مرنة.

  • getElementsByClassName() / getElementsByTagName(): مجموعات حيّة متغيرة.

3.3 تعديل السمات والأنماط

javascript
parag.setAttribute('class', 'lead'); parag.style.fontWeight = '700';

يلزم الحذر لضمان فصل منطق التطبيق عن العرض بالاعتماد على فئات CSS قدر الإمكان.

3.4 إدارة الأحداث

javascript
function handleClick(e) { /* … */ } button.addEventListener('click', handleClick, { once: true });

استخدام addEventListener بدل السمة onclick يُعزّز القابلية لإزالة المستمعات ويقي من التضارب.


4. نموذج أحداث DOM والتقاط مقابل التفقّع

  • الالتقاط (Capturing): يتدرّج الحدث من الجذر نزولًا إلى العنصر المستهدف.

  • الاستهداف (Target): يصل الحدث إلى العنصر ذاته.

  • التفقّع (Bubbling): يصعد الحدث عائدًا لأعلى الشجرة.

التحكّم في طور التنفيذ يتم عبر الوسيط useCapture أو الخيار { capture: true }.


5. اعتبارات الأداء: إعادة التدفق وإعادة الطلاء

5.1 ما المقصود بإعادة التدفق (Reflow)؟

يحدث عند تغيير خاصية تؤثر في تخطيط المستند، فيعيد المحرك حساب مواضع العناصر، ما يستهلك زمنًا حسابيًا.

5.2 التقليل من التكلفة

  • دمج التعديلات: استخدام DocumentFragment أو سلاسل .style.cssText.

  • القراءة ثم الكتابة: تجنّب التناوب بين عمليات القراءة والكتابة على الخصائص القابلة للقياس.

  • الاستفادة من الخاصية will-change في CSS للتنبيه المسبق.


6. واجهات حديثة مكملة للـDOM

6.1 واجهة Shadow DOM

توفر عزلًا للأساليب والأنماط داخل مكوّنات الويب من خلال:

javascript
const shadowRoot = element.attachShadow({ mode: 'open' });

6.2 قوالب HTML (Template)

عنصر