البرمجة

التنقل في DOM باستخدام جافاسكربت

جدول المحتوى

التنقل في شجرة DOM عبر جافاسكربت: المفاهيم الأساسية والتقنيات المتقدمة

تمثل شجرة DOM (Document Object Model) الهيكل الهرمي المنظم لمحتوى صفحات الويب، حيث تُترجم العناصر والعُقد (Nodes) ضمن الصفحة إلى بنية شجرية يمكن الوصول إليها ومعالجتها باستخدام لغة جافاسكربت. ومن خلال هذه البنية، يصبح بالإمكان التنقل بين العناصر، التعديل عليها، حذفها أو حتى إنشاء عناصر جديدة بشكل ديناميكي. تعتبر القدرة على التنقل في شجرة DOM والتحكم بها ركيزة أساسية لتطوير واجهات مستخدم ديناميكية وتفاعلية.

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


أولاً: ما هو DOM؟

DOM هو اختصار لـ Document Object Model، وهو واجهة برمجية تمثل هيكل الصفحة بصيغة كائنية (Object-Based)، تتيح للمطور التفاعل مع مكونات الصفحة HTML أو XML من خلال لغة جافاسكربت. تُحَوّل كل عناصر الصفحة — مثل العناصر

،

، وغيرها — إلى عُقد (Nodes) ضمن شجرة DOM.

الشجرة تتكون من عدة أنواع من العُقد، منها:

  • Document: تمثل كامل المستند.

  • Element: تمثل العناصر (tags) داخل الصفحة.

  • Text: تمثل النصوص داخل العناصر.

  • Attribute: تمثل خصائص العناصر.

  • Comment: تمثل التعليقات.


ثانياً: الهيكل الشجري لعناصر DOM

تُبنى شجرة DOM على شكل بنية هرمية، تبدأ من الجذر (document)، وتنقسم إلى عناصر فرعية تمثل هيكل الصفحة، كما هو موضح في النموذج التالي:

html
<html> <head> <title>مثالtitle> head> <body> <div> <p>نص داخل فقرةp> div> body> html>

الشجرة تكون على النحو التالي:

  • document

    • html

      • head

        • title

      • body

        • div

          • p

            • Text Node


ثالثاً: طرق الوصول إلى العناصر داخل DOM

هناك عدة طرق يمكن من خلالها الوصول إلى عناصر DOM:

1. الوصول عبر المعرف (ID)

javascript
var element = document.getElementById("myElement");

2. الوصول عبر اسم الوسم (Tag Name)

javascript
var paragraphs = document.getElementsByTagName("p");

3. الوصول عبر الفئة (Class Name)

javascript
var items = document.getElementsByClassName("item");

4. الوصول عبر المحددات (Selectors)

javascript
var div = document.querySelector("div.container"); var allItems = document.querySelectorAll("ul li");

رابعاً: العلاقات بين العُقد في DOM

لفهم كيفية التنقل داخل الشجرة، يجب معرفة العلاقات بين العُقد:

العلاقة التفسير
parentNode العقدة الأم للعقدة الحالية
childNodes قائمة بجميع الأبناء (بما فيهم النصوص)
children قائمة الأبناء من نوع Element فقط
firstChild / firstElementChild أول عنصر ابن
lastChild / lastElementChild آخر عنصر ابن
nextSibling / nextElementSibling الأخ التالي في نفس المستوى
previousSibling / previousElementSibling الأخ السابق في نفس المستوى

خامساً: التنقل العمودي (بين الأبناء والأمهات)

الانتقال إلى العنصر الأب:

javascript
var parent = element.parentNode;

الوصول إلى الأطفال:

javascript
var children = element.childNodes; // تشمل النصوص var elementsOnly = element.children; // عناصر فقط

الحصول على أول وآخر طفل:

javascript
var first = element.firstElementChild; var last = element.lastElementChild;

سادساً: التنقل الأفقي (بين الإخوة)

javascript
var next = element.nextElementSibling; var prev = element.previousElementSibling;

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


سابعاً: التحقق من نوع العقدة

يمكن التحقق من نوع العقدة باستخدام nodeType، حيث:

النوع القيمة الوصف
Element 1 عقدة عنصر
Attribute 2 خاصية
Text 3 نص
Comment 8 تعليق
Document 9 المستند

مثال:

javascript
if (node.nodeType === 1) { console.log("هذا عنصر HTML"); }

ثامناً: التكرار على العُقد

يمكن استخدام الحلقات للتكرار عبر عناصر DOM:

مثال باستخدام for:

javascript
var children = element.children; for (var i = 0; i < children.length; i++) { console.log(children[i].tagName); }

مثال باستخدام forEach (مع querySelectorAll):

javascript
document.querySelectorAll("p").forEach(function(p) { p.style.color = "blue"; });

تاسعاً: تعديل DOM أثناء التنقل

من خلال التنقل، يمكن تعديل المحتوى أو البنية:

تعديل النص:

javascript
element.textContent = "نص جديد";

تعديل HTML داخلي:

javascript
element.innerHTML = "نص جديد";

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

javascript
var newElement = document.createElement("span"); newElement.textContent = "عنصر جديد"; parent.appendChild(newElement);

حذف العناصر:

javascript
parent.removeChild(child);

عاشراً: تطبيقات عملية للتنقل داخل DOM

1. إنشاء قائمة ديناميكية

javascript
var list = document.createElement("ul"); var items = ["تفاحة", "موز", "برتقال"]; items.forEach(function(item) { var li = document.createElement("li"); li.textContent = item; list.appendChild(li); }); document.body.appendChild(list);

2. تلوين كل فقرة حسب ترتيبها

javascript
var paragraphs = document.querySelectorAll("p"); paragraphs.forEach(function(p, index) { if (index % 2 === 0) { p.style.backgroundColor = "lightgray"; } else { p.style.backgroundColor = "white"; } });

الحادي عشر: التعامل مع الأحداث أثناء التنقل

أثناء التنقل، يمكن إرفاق أحداث DOM ديناميكيًا:

javascript
var buttons = document.querySelectorAll("button"); buttons.forEach(function(btn) { btn.addEventListener("click", function() { alert("تم الضغط على الزر: " + btn.textContent); }); });

الثاني عشر: التقنيات المتقدمة في التعامل مع DOM

استخدام Tree Walker

TreeWalker يتيح التنقل عبر الشجرة حسب معايير معينة:

javascript
var walker = document.createTreeWalker( document.body, NodeFilter.SHOW_ELEMENT, null, false ); while(walker.nextNode()) { console.log(walker.currentNode.tagName); }

استخدام NodeIterator

javascript
var iterator = document.createNodeIterator( document.body, NodeFilter.SHOW_TEXT, null ); var node; while (node = iterator.nextNode()) { console.log(node.textContent.trim()); }

جدول يوضح أهم خصائص التنقل في DOM

الخاصية الوصف نوع العقد المعادة
parentNode العقدة الأم Node
children قائمة العناصر الأبناء HTMLCollection
childNodes كل الأبناء (عناصر + نصوص + تعليقات) NodeList
firstElementChild أول عنصر ابن Element
lastElementChild آخر عنصر ابن Element
nextElementSibling العنصر التالي في نفس المستوى Element
previousElementSibling العنصر السابق في نفس المستوى Element

الثالث عشر: الأداء والاعتبارات الأمنية

الأداء

  • يفضل استخدام children بدلًا من childNodes إذا لم تكن بحاجة للنصوص، لتقليل عدد العقد المعالجة.

  • التكرار باستخدام for أكثر كفاءة من forEach في الحلقات الكبيرة.

الأمان

  • تجنب استخدام innerHTML مع المحتوى المأخوذ من المستخدم، لتفادي XSS (تنفيذ أكواد خبيثة).

  • الأفضل استخدام textContent أو createElement وappendChild.


المراجع

  1. Mozilla Developer Network (MDN): https://developer.mozilla.org

  2. W3C DOM Standard: https://www.w3.org/DOM