البرمجة

البحث في DOM بجافاسكربت

البحث في DOM عبر *getElement و *querySelector في جافاسكربت

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


مفهوم DOM وأهمية البحث فيه

DOM هو تمثيل هيكلي لشجرة عناصر صفحة الويب، حيث يمثل كل عنصر فيها (كالوسوم tags والنصوص والخصائص) ككائن يمكن التفاعل معه برمجياً. تتيح جافاسكربت عبر DOM التحكم الكامل في الصفحة، من حيث تعديل النصوص، تغيير خصائص العناصر، إضافة أو حذف عناصر، وغيرها من التفاعلات الديناميكية.

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


الفرق بين دوال *getElement و *querySelector

هناك عدة طرق للبحث عن عناصر DOM، وأشهرها:

  • دوال getElement:

    • getElementById

    • getElementsByClassName

    • getElementsByTagName

  • دوال querySelector و querySelectorAll

1. getElementById

تُستخدم هذه الدالة للبحث عن عنصر واحد فقط بواسطة معرفه الفريد id. هذه الدالة تعود بكائن العنصر مباشرة أو بـ null إذا لم يكن موجوداً.

مثال:

javascript
const element = document.getElementById('header');

مميزاتها:

  • سريعة لأنها تبحث عن عنصر وحيد محدد.

  • لا تعيد مجموعة بل عنصر واحد فقط.

2. getElementsByClassName

تبحث عن جميع العناصر التي تحمل صنفاً معيناً (class) وتعيد مجموعة حية (HTMLCollection) من العناصر.

مثال:

javascript
const items = document.getElementsByClassName('menu-item');

مميزات:

  • تعيد مجموعة يمكن التكرار عليها.

  • المجموعة حية، أي أنها تعكس التغييرات التي تطرأ على DOM في الوقت الحقيقي.

3. getElementsByTagName

تُعيد جميع العناصر التي تحمل وسمًا معينًا في الصفحة، كمجموعة حية أيضًا.

مثال:

javascript
const paragraphs = document.getElementsByTagName('p');

4. querySelector

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

مثال:

javascript
const firstButton = document.querySelector('button.primary');

5. querySelectorAll

تعيد جميع العناصر المطابقة للمحدد CSS كـ مجموعة ثابتة (NodeList).

مثال:

javascript
const allLinks = document.querySelectorAll('a.external');

المقارنة التفصيلية بين دوال getElement و querySelector

الخاصية getElementById getElementsByClassName / TagName querySelector querySelectorAll
نوع البحث عن طريق id فقط عن طريق class أو اسم الوسم (tag) بواسطة محدد CSS (مثل: .class, #id, tag) بواسطة محدد CSS متعدد
النتيجة عنصر واحد أو null مجموعة حية (HTMLCollection) عنصر واحد أو null مجموعة ثابتة (NodeList)
قابلية التكرار على النتيجة لا نعم لا نعم
نوع المجموعة غير قابلة للتكرار (عنصر وحيد) حية (تنعكس التعديلات الحية في DOM عليها) غير قابلة للتكرار (عنصر وحيد) ثابتة (لا تتغير مع تغييرات DOM)
دعم محددات CSS لا لا نعم نعم
الأداء أفضل في البحث عن عنصر بواسطة id جيد عند البحث عن عناصر بحسب class أو tag أبطأ قليلاً بسبب تحليل CSS Selector أبطأ قليلاً
متى تستخدم عند الحاجة للوصول إلى عنصر معرف بـ id فريد عند البحث عن مجموعة عناصر متشابهة بسرعة عند الحاجة لاستعلام معقد أو مركب عند الحاجة لجلب كل العناصر المطابقة لمحدد CSS

استخدامات عملية ومقارنة تطبيقية

البحث بواسطة id

id هو معرف فريد من نوعه في الصفحة، لذلك getElementById هو الاختيار الأفضل والأسرع للوصول إلى عنصر معين بسرعة.

javascript
const mainTitle = document.getElementById('main-title'); mainTitle.textContent = 'مرحباً بالعالم!';

البحث بواسطة class

عندما تكون هناك عدة عناصر تشترك في نفس الصنف، يمكننا استخدام getElementsByClassName أو querySelectorAll.

javascript
const buttons = document.getElementsByClassName('btn'); for(let btn of buttons) { btn.style.color = 'red'; }

أو باستخدام querySelectorAll:

javascript
const buttons = document.querySelectorAll('.btn'); buttons.forEach(btn => btn.style.color = 'red');

البحث بواسطة محدد CSS مع تعقيد أعلى

باستخدام querySelector يمكن البحث ضمن عناصر معينة أو بناء محددات أكثر دقة مثل:

javascript
const firstActiveButton = document.querySelector('button.active.primary');

الفرق في التفاعل مع النتائج

  • المجموعة الحية (HTMLCollection) تتغير تلقائياً مع تغييرات DOM:

javascript
const items = document.getElementsByClassName('item'); console.log(items.length); // 3 const newItem = document.createElement('div'); newItem.className = 'item'; document.body.appendChild(newItem); console.log(items.length); // 4 (تحدث مباشرة)
  • المجموعة الثابتة (NodeList) لا تتغير تلقائياً:

javascript
const nodes = document.querySelectorAll('.item'); console.log(nodes.length); // 3 const newItem = document.createElement('div'); newItem.className = 'item'; document.body.appendChild(newItem); console.log(nodes.length); // 3 (ثابتة حتى إعادة البحث)

الأداء والفعالية

على الرغم من أن getElementById هو الأسرع بشكل كبير بسبب بساطة البحث عن معرف فريد، فإن querySelector وquerySelectorAll توفران مرونة لا تضاهى في اختيار العناصر باستخدام محددات CSS معقدة، مما يجعلها أدوات مفضلة في تطوير الواجهات الحديثة.

لكن يجب الحذر من الإفراط في استخدام querySelectorAll بكثرة داخل حلقات أو عمليات متكررة لأنها قد تؤثر سلباً على أداء الصفحة، خاصة إذا كانت صفحة تحتوي على آلاف العناصر.


أفضل الممارسات لاستخدام دوال البحث في DOM

  1. استخدم getElementById عند البحث عن عنصر وحيد معرف بشكل فريد، لتوفير الأداء.

  2. استخدم getElementsByClassName أو getElementsByTagName عند التعامل مع مجموعات كبيرة من العناصر المتشابهة، خاصة إذا كنت تحتاج إلى أن تتفاعل مع التغييرات الحية في DOM.

  3. عند الحاجة إلى استعلامات معقدة أو متداخلة، استخدم querySelector أو querySelectorAll مع محددات CSS مناسبة.

  4. تجنب استدعاء دوال البحث بشكل متكرر داخل حلقات إذا كان بالإمكان تخزين النتائج مؤقتًا، لتحسين الأداء.

  5. كن واعياً لأن getElementsByClassName و getElementsByTagName تُرجع مجموعات حية، وهذا قد يؤثر على التكرار إذا قمت بتعديل DOM أثناء التكرار.

  6. استغل قوة محددات CSS في querySelector لزيادة دقة البحث وتقليل الحاجة إلى تنفيذ عمليات بحث متعددة.


حالات استخدام متقدمة مع querySelector

يمكن الاستفادة من querySelector في حالات متعددة معقدة تشمل:

  • اختيار عنصر بناءً على صفاته، مثلاً عنصر الذي يحمل صفة type="text":

javascript
const textInput = document.querySelector('input[type="text"]');
  • البحث داخل عنصر معين فقط (scope):

javascript
const container = document.getElementById('container'); const firstButton = container.querySelector('button');
  • اختيار العنصر الذي يحتوي على نص معين عبر تحديد الصفات:

javascript
const activeLinks = document.querySelectorAll('a.active[href^="https"]');

التعامل مع مجموعات العناصر المسترجعة

التكرار

  • عند استخدام getElementsByClassName أو getElementsByTagName يتم الحصول على HTMLCollection، والذي يمكن التكرار عليه بواسطة for أو for...of في المتصفحات الحديثة، ولكن لا تدعم جميع المتصفحات الحديثة استخدام دوال مثل forEach مباشرة على HTMLCollection.

  • بينما querySelectorAll يعيد NodeList، الذي يدعم forEach مباشرة.

تحويل المجموعات إلى مصفوفات

في بعض الحالات نحتاج إلى تحويل المجموعات إلى مصفوفات لتطبيق دوال مثل map أو filter:

javascript
const nodes = document.querySelectorAll('.item'); const nodesArray = Array.from(nodes); const filtered = nodesArray.filter(node => node.textContent.includes('نص معين'));

التعامل مع التوافق والمتصفحات

جميع الدوال المذكورة مدعومة بشكل واسع في جميع المتصفحات الحديثة، بما فيها Chrome وFirefox وEdge وSafari. ومع ذلك، قبل سنوات، كانت هناك فروقات طفيفة في دعم querySelector و querySelectorAll في المتصفحات القديمة، ولكن حالياً هذه الدوال أصبحت معياراً أساسياً لا غنى عنه في تطوير الويب الحديث.


الخلاصة

البحث في DOM باستخدام دوال getElement و querySelector يمثل جوهر التفاعل مع صفحات الويب في جافاسكربت. لكل طريقة مزاياها واستخداماتها، ويجب على المطور اختيار الأنسب منها حسب الحاجة، سواء كانت سرعة الأداء، مرونة الاستعلام، أو التعامل مع مجموعات العناصر.

  • getElementById يوفر أسرع طريقة للوصول إلى عنصر معرف.

  • getElementsByClassName و getElementsByTagName تعطي مجموعات حية لعناصر متشابهة.

  • querySelector و querySelectorAll تمنح المرونة والقدرة على استعلام دقيق باستخدام محددات CSS معقدة.

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


المصادر والمراجع