يسمح لنا الـ DOM بالقيام بأي شيء مع العناصر ومحتوياتها، ولكن أولاً يجب علينا الوصول إلى كائن DOM المقابل.
تبدأ جميع العمليات على الـ DOM مع كائن document. هذه هي النقطة الرئيسية للدخول إلى DOM. من خلاله يمكننا الوصول إلى أي عقدة.
هذه صورة لروابط تسمح بالسفر بين عقد DOM:
دعونا نناقشهم بمزيد من التفصيل.
في الأعلى: documentElement و body
تتوفر العقد الشجرية العليا مباشرة كخصائص document:
html>=document.documentElement>- العقدة الوثيقة العليا هي
document.documentElement. هذه هي عقدة DOM للعلامة<html>. body>=document.body>- عقدة DOM أخرى مستخدمة على نطاق واسع هي عنصر
body>–document.body>. head>=document.head>- تتوفر علامة
<head>كـdocument.head.
document.bodyقيمتهnullلا يمكن للبرنامج النصي الوصول إلى عنصر غير موجود في لحظة التشغيل.
على وجه الخصوص، إذا كان البرنامج النصي داخل <head>، فإن document.body غير متاح، لأن المتصفح لم يقرأه بعد.
لذلك، في المثال أدناه يظهر التنبيه الأول null:
<html>
<head>
<script>
alert( "من HEAD: " + document.body ); // null، لا يوجد <body> بعد
</script>
</head>
<body>
<script>
alert("من BODY: " + document.body); // HTMLBodyElement، الآن يوجد
</script>
</body>
</html>
null DOM تعنى “غير موجود”في ال DOM، تعني قيمة null “غير موجود” أو “لا يوجد مثل هذه العقدة”.
الأطفال: childNodes، firstChild، lastChild
هناك مصطلحان سنستخدمهما من الآن فصاعدًا:
- عقد الأطفال (أو الأطفال) – العناصر التي هي أطفال مباشرين. بعبارة أخرى، هم متداخلون بالضبط في المعطى. على سبيل المثال،
<head>و<body>هما أطفال عنصر<html>. - السلالة – جميع العناصر المتداخلة في المعطى، بما في ذلك الأطفال وأطفالهم وهكذا.
على سبيل المثال، هنا <body> لديه أطفال <div> و <ul> (وبعض العقد النصية الفارغة):
<html>
<body>
<div>بداية</div>
<ul>
<li>
<b>معلومات</b>
</li>
</ul>
</body>
</html>
…وسلالة <body> ليست فقط الأطفال المباشرين <div>، <ul> ولكن أيضًا العناصر المتداخلة بشكل أعمق، مثل <li> (طفل <ul>) و <b> (طفل <li>) – الشجرة الفرعية بأكملها.
تدرج مجموعة childNodes جميع عقد الأطفال، بما في ذلك العقد النصية.
يوضح المثال أدناه أطفال document.body:
<html>
<body>
<div>بداية</div>
<ul>
<li>معلومات</li>
</ul>
<div>نهاية</div>
<script>
for (let i = 0; i < document.body.childNodes.length; i++) {
alert( document.body.childNodes[i] ); // Text, DIV, Text, UL, ..., SCRIPT
}
</script>
...المزيد من المحتوى...
</body>
</html>
يرجى ملاحظة تفصيل مثير للاهتمام هنا. إذا قمنا بتشغيل المثال أعلاه ، فإن آخر عنصر يظهر هو <script>. في الواقع ، يحتوي المستند على المزيد من المحتوى أدناه ، ولكن في لحظة تنفيذ البرنامج النصي لم يقرأ المتصفح بعد ، لذلك لا يرى البرنامج النصي.
توفر الخصائص firstChild و lastChild إمكانية الوصول السريع إلى الأطفال الأول والأخير.*
إنهم مجرد اختصارات. إذا كانت هناك عقد فرعية ، فإن التالي صحيح دائمًا:
elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
هناك أيضًا وظيفة خاصة elem.hasChildNodes() للتحقق مما إذا كانت هناك أي عقد فرعية.
مجموعات DOM
كما نرى ، يبدو childNodes كمصفوفة. ولكن في الواقع ليس مجموعة ، بل مجموعة – كائن قابل للتكرار يشبه المصفوفة.
هناك نتيجتان مهمتان:
- يمكننا استخدام
for..ofللتكرار عليه:
for (let node of document.body.childNodes) {
alert(node); // يظهر جميع العقد من المجموعة
}
هذا لأنه قابل للتكرار (يوفر خاصية Symbol.iterator ، كما هو مطلوب).
- لن تعمل طرق المصفوفة ، لأنها ليست مصفوفة:
alert(document.body.childNodes.filter); // undefined (لا يوجد طريقة تصفية!)
الشيء الأول جميل. الثانية محتملة ، لأنه يمكن استخدام Array.from لإنشاء مصفوفة “حقيقية” من المجموعة ، إذا كانت نرغب في استخدام طرق المصفوفات: