querySelector وquerySelectorAll
اعثر على عناصر مفردة ومتعددة باستخدام سلاسل محددات CSS، وافهم الفرق بين NodeList وHTMLCollection.
querySelector وquerySelectorAll درس مجاني في Frontend Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Frontend Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Frontend Academy 4 دروس في المجموع.
ما هو DOM؟
إن نموذج كائن المستند هو شجرة من كائنات JavaScript تمثل بنية HTML. يتفاعل JavaScript مع DOM لقراءة العناصر وتعديلها وإضافتها وإزالتها، مما يجعل صفحات الويب ديناميكية.
getElementById
المحدِّد الكلاسيكي. يعيد document.getElementById('myId') العنصر الذي يحمل ذلك المعرّف، أو null إذا لم يعثر عليه. وهو سريع، لكنه يعمل مع المعرّفات فقط.
const header = document.getElementById('site-header');
if (header) {
header.style.backgroundColor = 'navy';
}querySelector — عنصر واحد
يعيد document.querySelector(cssSelector) أول عنصر يطابق أي محدد CSS. ويعيد null إذا لم يُعثر على أي عنصر. وهو أكثر مرونة من getElementById.
const btn = document.querySelector('.btn-primary');
const input = document.querySelector('input[type="email"]');
const hero = document.querySelector('#hero h1');querySelectorAll — عناصر متعددة
يعيد document.querySelectorAll(cssSelector) قائمة NodeList ثابتة تضم جميع العناصر المطابقة. وهي ليست مصفوفة حيّة، لذلك يجب تكرار عناصرها. استخدموا Array.from() أو الصياغة المنبسطة لاستخدام أساليب المصفوفات.
const cards = document.querySelectorAll('.card');
cards.forEach(card => card.classList.add('loaded'));
// Convert to array for array methods:
const hrefs = Array.from(document.querySelectorAll('a')).map(a => a.href);الاستعلامات المقيّدة النطاق
يمكن استدعاء querySelector على أي عنصر للبحث داخل تلك الشجرة الفرعية فقط، وليس المستند بأكمله. وهذا أكثر كفاءة ويمنع تحديد عناصر من أجزاء أخرى من الصفحة عن طريق الخطأ.
const nav = document.querySelector('#main-nav');
const links = nav.querySelectorAll('a'); // only links inside #main-navNodeList مقابل HTMLCollection
إن NodeList (من querySelectorAll) ثابتة، فهي تعكس حالة DOM وقت الاستعلام. أما HTMLCollection (من getElementsByClassName وما شابه) فحيّة، إذ تتحدّث تلقائيًا عند تغيّر DOM. وكلاهما يشبه المصفوفات، لكنهما ليسا مصفوفتين.
التنقّل في DOM
يمكنكم التنقّل من أي عنصر باستخدام: element.parentElement، element.children، element.firstElementChild، element.lastElementChild، element.nextElementSibling، element.previousElementSibling.
const list = document.querySelector('ul');
console.log(list.children.length); // number of li elements
console.log(list.firstElementChild); // first li
console.log(list.parentElement); // ul's parentالتحقق من وجود عنصر
تحققوا دائمًا من أن querySelector لم يُعد null قبل استخدام النتيجة، وخصوصًا للعناصر التي قد لا تكون موجودة في كل صفحة.
const modal = document.querySelector('.modal');
if (modal) {
// safe to use modal here
modal.classList.add('open');
}matches() وclosest()
يعيد element.matches(selector) القيمة true إذا طابق العنصر المحدد. وتصعد element.closest(selector) في شجرة DOM وتعيد أول سلف يطابق المحدد، أو null.
const item = document.querySelector('.list-item');
console.log(item.matches('.active')); // false
// Event delegation: find the clicked card
document.addEventListener('click', (e) => {
const card = e.target.closest('.card');
if (card) card.classList.toggle('selected');
});contains()
يعيد parentElement.contains(childElement) القيمة true إذا كان العنصر الابن داخل العنصر الأب، أو كان هو العنصر الأب نفسه. ويفيد ذلك في التحقق مما إذا حدثت نقرة خارج نافذة حوار أو قائمة منسدلة.
document.addEventListener('click', (e) => {
const menu = document.querySelector('.dropdown-menu');
if (!menu.contains(e.target)) {
menu.hidden = true; // clicked outside
}
});الأداء: تقليل استعلامات DOM
استعلامات DOM ليست مجانية. خزّنوا النتيجة في متغير بدلًا من استدعاء querySelector مرارًا. وفي الحلقات، اجمعوا قراءات DOM معًا وكتابات DOM معًا لتجنب إعادة حساب التخطيط المتكررة.
// Bad — queries DOM in every iteration:
for (let i = 0; i < 100; i++) {
document.querySelector('#counter').textContent = i;
}
// Good — cache the element:
const counter = document.querySelector('#counter');
for (let i = 0; i < 100; i++) counter.textContent = i;تحقق سريع
أي أسلوب يعيد قائمة NodeList ثابتة تضم جميع العناصر المطابقة؟
مراجعة: تحديد عناصر DOM
يعيد querySelector أول تطابق. ويعيد querySelectorAll جميع التطابقات في قائمة NodeList ثابتة. قيّدوا الاستعلامات بشجرة فرعية لتحسين الكفاءة. خزّنوا نتائج الاستعلامات مؤقتًا. استخدموا closest() لتفويض الأحداث. تحققوا دائمًا من null قبل استخدام عنصر جرى الاستعلام عنه.
الأسئلة الشائعة
هل درس «querySelector وquerySelectorAll» مجاني؟
نعم — نص درس «querySelector وquerySelectorAll» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Frontend Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Frontend Academy 4 دروس في المجموع.
ماذا ستتعلم في «querySelector وquerySelectorAll»؟
اعثر على عناصر مفردة ومتعددة باستخدام سلاسل محددات CSS، وافهم الفرق بين NodeList وHTMLCollection. تتمرن على Frontend Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Frontend Academy؟
لا تُشترط خبرة سابقة. Frontend Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «querySelector وquerySelectorAll»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Frontend Academy هذا؟
نعم. كل درس في Frontend Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- querySelector وquerySelectorAll
- addEventListener وكائن Event
- تغيير المحتوى: textContent وinnerHTML وclassList
- إنشاء العناصر وإلحاقها