١٥ ديسمبر ٢٠٢١

نموذج كائن المستند DOM

تُعد العلامات (الوسوم) عصب مستند HTML.

وفقًا لنموذج كائن المستند (DOM)، فإن كل علامة (وسم) من علامات HTML يُعد كائنًا. وكل العلامات المُدرجة داخل هذه العلامة تُعد أبناءً لها. كما يُعد النص الموجود داخل هذه العلامة كائنًا أيضا.

يُمكن الوصول إلى جميع تلك الكائنات باستخدام جافا سكريبت؛ كما يُمكن استخدامهم لتعديل الصفحة.

على سبيل المثال، فإن document.body هو الكائن المُمثل للعلامة <body>.

سيؤدي تشغيل الشفرة التالية لجعل خلفية العلامة <body> أحمر اللون لمدة ثلاث ثوانٍ:

document.body.style.background = 'red'; // لجعل الخلفية حمراء اللون

setTimeout(() => (document.body.style.background = ''), 3000); // لإزالة اللون من الخلفية

اُستخدم style.background في هذا المثال لتغيير لون الخلفية الخاصة بـ document.body؛ ومع ذلك، فإنه يوجد العديد من الخصائص الأخرى لاستخدامها، مثل:

  • innerHTML – محتوى HTML للعقدة.
  • offsetWidth – عرض العقدة (بالبكسل).
  • …وغيرها.

لاحقا، سنتعلم المزيد من الطرق للتعامل مع نموذج كائن المستند DOM؛ ولكن قبل ذلك، ينبغي معرفة هيكله.

مثال على نموذج كائن المستند DOM

لنبدأ بالمستند التالي:

<!DOCTYPE html>
<html>
  <head>
    <title>عن الظباء</title>
  </head>
  <body>
    حقائق عن الظباء
  </body>
</html>

يُمثل نموذج كائن المستند الـ HTML كشجرة من العلامات. إليك كيف تبدو:

في الصورة أعلاه، يؤدي الضغط على أي عقدة عنصر إلى تمديد أو طي أبنائها من العلامات.

كل عقدة في هذه الشجرة تُمثل كائنًا.

العلامات ما هي إلا عقد العنصر (أو تُعرف بالعناصر اختصارا)، وهي المُكونة لبنية الشجرة. <html> هو الجذر، ويُمثل كلا من الـ <head> والـ <body> أبناؤه، إلخ.

يُشكل النص الموجود داخل العناصر عقد النصوص، والمسمى #text. تشتمل عقدة النص على سلسلة واحدة فقط. قد لا تحتوي عقدة النص على أية أبناء، وهي دائما تُمثل ورقة في هذه الشجرة.

على سبيل المثال، العلامة <title> تحتوي على النص "عن الظباء".

يرجى ملاحظة الأحرف الخاصة في العقد النصية:

  • سطر جديد: (تُعرف في جافا سكريبت بـ \n)
  • مسافة:

كلا من المسافات والأسطر الجديدة هي أحرف صالحة مثل الحروف والأرقام. وهي جميعا تُمثل عقد النص وتصبح جزءًا من نموذج كائن المستند. لذلك، وعلى سبيل المثال، فإن علامة <head> في المثال أعلاه تحتوي على بعض المسافات قبل الـ <title>، وهذا النص يُصبح عقدة #text (والتي تحتوي فقط على سطر جديد وبعض المسافات).

هناك استثناءان فقط مهمان:

  1. يتم تجاهل المسافات والأسطر الجديدة التي تأتي قبل الـ <head> وذلك لأسباب تاريخية.
  2. إذا وُضع شيء بعد الـ </body>، فإنه سيُنقل تلقائيا إلى داخل الـ body وذلك في نهايته؛ حيث تتطلب مواصفات HTML أن يكون كل المحتوى داخل الـ <body>. ولذلك، فإنه من غير الممكن وجود أية مسافات بعد الـ </body>.

كل شيء يكون واضحا في بقية الحالات، فإذا كانت هناك مسافات في المستند (تماما مثل أي حرف)، فإنها تُصبح عقد نص في نموذج كائن المستند، وإذا اُزيلت فإن أيا منها لن يكون موجودا.

فيما يلي لا توجد عقد نصية تحتوي على مسافات فقط:

<!DOCTYPE html>
<html>
  <head>
    <title>عن الظباء</title>
  </head>
  <body>
    حقائق عن الظباء.
  </body>
</html>
عادة ما تُخفى المسافات في بداية/نهاية السلاسل، وفي العقد النصية التي تحتوي على مسافات فقط من الأدوات

أدوات المتصفح (التي سيتم تغطيتها قريبا) والتي تعمل مع نموذج كائن المستند لا تعرض عادة المسافات في بداية/نهاية النص، والعقد النصية الفارغة (فواصل الأسطر) بين العلامات.

وبهذه الطريقة، توفر أدوات المطور مساحة الشاشة.

في صور نموذج كائن المستند الأخرى، سنحذفها أحيانا عندما تكون غير متصلة بالموضوع. عادة، لا تؤثر هذه المسافات على كيفية عرض المستند.

التصحيح التلقائي

عندما يواجه المتصفح ترميز HTML مكتوب بشكل غير صحيح، فإنه يقوم بتصحيحه تلقائيا عند إنشاء نموذج كائن المستند DOM.

على سبيل المثال، توجد العلامة <html> في الأعلى؛ وذلك حتى في حال عدم تواجدها في المستند، فإنها تظل متواجدة في نموذج كائن المستند؛ وذلك لأن المتصفح يقوم بإنشائها. وينطبق الأمر ذاته على علامة <body>.

مثال: إذا كان ملف الـ HTML يحتوى فقط على كلمة "مرحبا"، فإن المتصفح سيقوم بتضمينه داخل علامتي <html> و <body>، كما سيقوم بإضافة علامة <head>؛ وعليه يكون نموذج كائن المستند كما يلي:

أثناء إنشاء نموذج كائن المتسند، تقوم المتصفحات تلقائيا بمعاجلة الأخطاء في المستند وإغلاق العلامات وما إلى ذلك.

مستند به علامات غير مغلقة:

<p>
  مرحبا
  <li>أمي</li>
  <li>و</li>
  <li>أبي</li>
</p>

…سيصبح نموذج كائن مستند طبيعيا، وذلك عندما يقرأ المتصفح العلامات ويُعيد الأجزاء المفقودة:

Tables always have <tbody>

ملف HTML:

<table id="table">
  <tr>
    <td>1</td>
  </tr>
</table>

بنية نموذج كائن المستند ستصبح:

You see? The <tbody> appeared out of nowhere. We should keep this in mind while working with tables to avoid surprises.

أنواع العقد الأخرى

هناك بعض أنواع العقد الأخرى إلى جانب العناصر وعقد النص.

على سبيل المثال، التعليقات:

<!DOCTYPE HTML>
<html>
<body>
  حقائق عن الظباء.
  <ol>
    <li>الظبي ذكي.</li>
    <!-- تعليق -->
    <li>...وحيوان ماكر!</li>
  </ol>
</body>
</html>

يُمكننا أن نرى هنا نوعا جديدا من عقد الشجرة – وهي عقدة التعليق، والمسماة #comment، بين عقدتين نصيتين.

قد نتسائل – لماذا أُضيف تعليق إلى نموذج كائن المستند؟ فهو لا يؤثر على التمثيل البصري بأي شكل من الأشكال. ولكن هناك قاعدة – إذا كان وُجد شيء في HTML فإنه يجب أن يكون موجود أيضا في شجرة نموذج كائن المستند.

كل شيء في HTML، حتى التعليقات، تصبح جزءا من نموذج كائن المستند.

Even the <!DOCTYPE...> directive at the very beginning of HTML is also a DOM node. It’s in the DOM tree right before <html>. Few people know about that. We are not going to touch that node, we even don’t draw it on diagrams, but it’s there.

كائن المستند، والذي يُمثل المستند بأكمله، يُكون عقدة من نموذج كائن المستند أيضا.

هناك 12 نوع من العقد. ومن الناحية العملية، نعمل عادة مع 4 منهم:

  1. المستند document – يُمثل “نقطة الدخول” إلى نموذج كائن المستند.
  2. عقد العناصر element nodes – وهي علامات HTML، وتُمثل كتل بناء الشجرة.
  3. العقد النصية text nodes – وتحتوي على نص.
  4. التعليقات comments – في بعض الأحيان يُمكن وضع معلومات بها، لن يتم عرض المعلومات، ولكن يُمكن قرائتها من نموذج كائن المستند باستخدام جافا سكريبت.

انظر بنفسك

لمشاهدة بنية نموذج كائن المستند مباشرة، جرب استخدام Live DOM Viewer. ما عليك سوى الكتابة في المستند، وسيظهر كنموذج كائن مستند في الحال.

هناك طريقة أخرى لاستكشاف نموذج كائن المستند وهي استخدام أدوات مطور المتصفح. وهذا ما نستخدمه في الواقع أثناء التطوير.

للقيام بذلك، افتح صفحة الويب elk.html، وشغّل أدوات مطور المتصفح، وانتقل إلى علامة التبويب العناصر Elements.

يجب أن تبدو مثل هذه:

يُمكنك رؤية نموذج كائن المستند، والنقر على العناصر، والإطلاع على تفاصيلها، وما إلى ذلك.

يُرجى ملاحظة أن بنية نموذج كائن المستند في أدوات المطورين مُبسطة. حيث يتم عرض العُقد النصية كنص فقط؛ ولا توجد أي عُقد نصية “فارغة” (مسافة فقط) على الإطلاق. وهذا جيد، لأننا مهتمون في معظم الأحيان بعُقد العناصر.

يسمح لنا النقر على الزر في الزأوية اليُسرى العُليا باختيار عقدة من صفحة الويب باستخدام الفأرة (أو أجهزة التأشير الأخرى) و “فحصها” (الانتقال إليها في علامة تبويب العناصر). وهذا يكون رائعا عندما يكون لدينا صفحة HTML ضخمة (ونموذج كائن مستند ضخم بالتبعية) ونود أن نرى مكان عنصر معين فيه.

هناك طريقة أخرى للقيام بذلك وهي النقر بزر الفأرة الأيمن على صفحة الويب واختيار “فحص Inspect” في قائمة السياق.

يوجد في الجزء الأيمن من الأدوات علامات التبويب الفرعية التالية:

  • Styles – يُمكننا رؤية تنسيقات CSS المطبقة على العنصر الحالي قاعدة بعد الأخرى، بما في ذلك القواعد الذاتية (باللون الرمادي). ويُمكن تحرير كل شيء تقريبا، بما في ذلك الأبعاد/margins/paddings في الصندوق أدناه.
  • Computed – يُمكننا من رؤية CSS مطبقة على العنصر حسب الخاصية: لكل خاصية يُمكننا أن نرى القاعدة التي تمنحها (بما في ذلك CSS الموروث وما إلى ذلك).
  • Event Listeners – لرؤية event listeners المرتبطة بعناصر نموذج كائن المستند (سيتم تغطيتهم في الجزء التالي من البرنامج التعليمي). -…وما إلى ذلك.

أفضل طريقة لدراستها هي النقر عليها وحولها. معظم القيم قابلة للتعديل في مكانها.

التفاعل مع الـ Console

أثناء العمل مع نموذج كائن المستند، قد نرغب أيضا في تطبيق جافا سكريبت عليه. مثل: إيجاد عقدة وتشغيل بعض التعليمات البرمجية لتعديلها، وذلك لرؤية النتيجة. إليك بعض النصائح للتنقل بين علامتي التبويب Elements و console.

في البداية:

  1. حدد أول عنصر <li> في تبويب Elements.
  2. اضغط مفتاح:Esc– سيفتح الـ console أسفل علامة تبويب Elements مباشرة.

الآن أخر عنصر تم تحديده متاح كـ $0، والعنصر الذي كان مُحددا قبله هو $1 إلخ.

يُمكننا تشغيل الأوامر عليهم. على سبيل المثال، $0.style.background = 'red' يجعل عنصر القائمة المحدد أحمر، مثل هذا:

هذه هي كيفية الحصول على عقدة من علامة تبويب Elements في console.

وعلى عكس المثال السابق، فإذا كان هناك متغير يُشير إلى عقدة من نموذج كائن المستند، فيُمكننا استخدام الأمر فحص(العقدة) inspect(node) في الـ Console لرؤيته في جزء العناصر.

أو يُمكننا فقط إخراج عقدة نموذج كائن المستند في الـ console واستكشافها “في مكانها”، مثل: document.body أدناه:

وهذا بالطبع لأغراض التصحيح debugging. بدءا من الفصل التالي، سنقوم بالوصول إلى نموذج كائن المستند وتعديله باستخدام جافا سكريبت.

تُساعد أدوات مطور المتصفح مساعدة كبيرة في التطوير: يُمكننا استكشاف نموذج كائن المستند وتجربة الأشياء ومعرفة الأخطاء.

الملخص

يتم تمثيل مستند HTML/XML داخل المتصفح باعتباره شجرة نموذج كائن المستند DOM Tree.

  • تصبح العلامات عقد عناصر وتُشكل البنية.
  • تصبح النصوص عقد نصية. -…إلخ، كل شيء في HTML له مكانه في نموذج كائن المستند، حتى التعليقات.

يُمكننا استخدام أدوات المطورين لفحص نموذج كائن المستند وتعديله يدويا.

قمنا هنا بتغطية الأساسيات والإجراءات الأكثر استخدامًا والأكثر أهمية للبدء بها. هناك وثائق شاملة حول Chrome Developer Tools على https://developers.google.com/web/tools/chrome-devtools. أفضل طريقة لتعلم الأدوات هي بالنقر هنا وهناك، وقراءة القوائم: حيث مُعظم الخيارات واضحة. لاحقًا، عندما تعرفها مُجملة، اقرأ وثائقها وتعلم الباقي.

تحتوي عقد نموذج شجرة المستند على خصائص وأساليب تتيح لنا التنقل بينها وتعديلها والتنقل في الصفحة والمزيد. سنتنأولها في الفصول القادمة.

خريطة الدورة التعليمية

التعليقات

إقرأ هذا قبل أن تضع تعليقًا…
  • إذا كان لديك اقتراحات أو تريد تحسينًا - من فضلك من فضلك إفتح موضوعًا فى جيتهاب أو شارك بنفسك بدلًا من التعليقات.
  • إذا لم تستطع أن تفهم شيئّا فى المقال - وضّح ماهو.
  • إذا كنت تريد عرض كود استخدم عنصر <code> ، وللكثير من السطور استخدم <pre>، ولأكثر من 10 سطور استخدم (plnkr, JSBin, codepen…)