Elementlarni qidirish: getElement*, querySelector*
DOM navigatsiyasi xossalari qo'shni tugunlar bir-biriga yaqin joylashganda juda qulay. Ammo elementlar bir-biridan uzoqda bo'lsa-chi? Sahifadagi istalgan elementni uning DOM'dagi o'rniga bog'liq bo'lmagan holda topish uchun maxsus qidiruv metodlari bor. Ushbu darsda ularni chuqur o'rganamiz.
document.getElementById yoki id
Agar elementning id atributi bo'lsa, uni document.getElementById(id) orqali topamiz, u qayerda bo'lishidan qat'i nazar:
<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
let elem = document.getElementById('elem');
elem.style.background = 'red';
</script>
Bundan tashqari, idga ega global o'zgaruvchi avtomatik yaratiladi โ uning nomi id qiymatiga teng bo'ladi:
<div id="elem"></div>
<script>
// elem โ id="elem" bo'lgan elementga havola
alert(elem); // <div id="elem">
// window.elem ham shu
alert(window.elem === elem); // true
</script>
idni chalkashtirib yuborishi mumkin. Agar kodda elem nomli o'zgaruvchi e'lon qilsak, u avtomatik global'ni bekor qiladi. Har doim document.getElementByIddan foydalanish yaxshi amaliyot.idga ega bo'lsin. Agar bir nechta element bir xil idga ega bo'lsa, qidiruv metodlarining xatti-harakati oldindan aytib bo'lmaydigan bo'ladi.getElementById faqat document obyektida chaqiriladi, oddiy elementlarda emas: elem.getElementById(...) mavjud emas!querySelectorAll
Eng ko'p qirrali metod โ elem.querySelectorAll(css). U berilgan CSS selektorga mos keluvchi barcha elementlarni qaytaradi.
<ul>
<li>Bu</li>
<li>test</li>
</ul>
<ul>
<li>ancha</li>
<li>uzun</li>
</ul>
<script>
// har bir <ul>ning oxirgi <li>sini topamiz
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML); // 'test', 'uzun'
}
</script>
Bu metod juda kuchli, chunki har qanday CSS selektorni qo'llash mumkin. Hatto :hover va :active kabi psevdo-klasslar ham qo'llab-quvvatlanadi. Masalan, document.querySelectorAll(':hover') ustiga sichqoncha turgan elementlar to'plamini beradi.
querySelector
elem.querySelector(css) chaqiruvi berilgan CSS selektorga mos birinchi elementni qaytaradi.
Boshqacha aytganda, natija querySelectorAll(css)[0] bilan bir xil, ammo querySelectorAll barcha elementlarni topib to'plamdan birinchisini olsa, querySelector faqat birinchisini topadi. Shuning uchun u tezroq va yozishda ham qisqaroq:
let elem = document.querySelector('.my-class'); // birinchi mos element
matches
Oldingi metodlar DOM'da qidirar edi. elem.matches(css) esa hech narsa qidirmaydi. U faqat elem berilgan CSS selektorga mosligini tekshiradi va true yoki false qaytaradi.
Bu qandaydir to'plam (masalan, massiv) ustidan aylanib, kerakli elementlarni filtrlaganda foydali:
<a href="http://example.com/file.zip">...</a>
<a href="http://ya.ru">...</a>
<script>
// faqat href oxiri zip bilan tugaydigan havolalar
for (let elem of document.querySelectorAll('a')) {
if (elem.matches('a[href$=".zip"]')) {
alert('Arxivga havola: ' + elem.href);
}
}
</script>
closest
Elementning ajdodlari (ancestors) โ bu uning otasi, otasining otasi, uning otasi va hokazo. Ajdodlar birgalikda yuqoriga, ildizgacha bo'lgan zanjirni tashkil qiladi.
elem.closest(css) metodi berilgan CSS selektorga mos keluvchi eng yaqin ajdodni qidiradi. elemning o'zi ham qidiruvga kiritiladi.
Boshqacha aytganda, closest elementning o'zidan boshlab yuqoriga ko'tarilib boradi va har bir ajdodni selektorga tekshiradi. Mos kelgani topilsa, qidiruv to'xtaydi va shu ajdod qaytariladi:
<h1>Sarlavha</h1>
<div class="contents">
<ul class="book">
<li class="chapter">Bob 1</li>
<li class="chapter">Bob 2</li>
</ul>
</div>
<script>
let chapter = document.querySelector('.chapter'); // LI
alert(chapter.closest('.book')); // UL
alert(chapter.closest('.contents')); // DIV
alert(chapter.closest('h1')); // null (h1 ajdod emas)
</script>
closest hodisalarni qayta ishlashda (event delegation) juda ko'p ishlatiladi: bosilgan element atrofidagi kerakli "o'rovchi" (wrapper) elementni topish uchun ideal vosita.getElementsBy* metodlari
Elementlarni teg, klass va boshqalar bo'yicha qidiruvchi eski metodlar ham bor. Bugun ular asosan querySelector foydasiga o'z ahamiyatini yo'qotmoqda, ammo eski kodlarda hali ko'p uchraydi:
elem.getElementsByTagName(tag)โ berilgan tegli elementlarni qidiradi va to'plam qaytaradi.tago'rniga"*"berilsa, "barcha teglar" degani;elem.getElementsByClassName(className)โ berilgan klassga ega elementlar to'plami;document.getElementsByName(name)โ hujjat bo'yicha berilgannameatributiga ega elementlar to'plami (kamdan-kam ishlatiladi).
// hujjatdagi barcha <div>lar
let divs = document.getElementsByTagName('div');
// jadvaldagi barcha input'larning qiymatini oling
let inputs = table.getElementsByTagName('input');
for (let input of inputs) {
alert( input.value );
}
getElementByTagName (bittalik) โ mavjud emas! To'g'ri nomi getElementsByTagName (ko'plik, chunki bir nechta element qaytaradi). Aksincha, getElementById bitta element qaytargani uchun "s"siz yoziladi.getElementsByTagName to'plam qaytarishini unutib, uni to'g'ridan-to'g'ri element deb ishlatadi: document.getElementsByTagName('input').value ishlamaydi! To'g'risi โ element indeksini olish: document.getElementsByTagName('input')[0].value.Jonli (live) va statik to'plamlar
Bu yerda muhim farq bor:
- Barcha
getElementsBy*metodlari jonli (live) to'plam qaytaradi. Bunday to'plamlar hujjatning joriy holatini har doim aks ettiradi va o'zgarishlarda avtomatik yangilanadi; - Aksincha,
querySelectorAllstatik to'plam qaytaradi. Bu "muzlatib qo'yilgan" massiv kabi โ chaqiruv paytidagi holatni saqlaydi va keyingi o'zgarishlar unga ta'sir qilmaydi.
// jonli to'plam
let divs = document.getElementsByTagName('div');
alert(divs.length); // masalan, 1
// hujjatga yangi <div> qo'shsak...
document.body.append(document.createElement('div'));
alert(divs.length); // 2 (avtomatik yangilandi!)
// statik to'plam
let divs = document.querySelectorAll('div');
alert(divs.length); // masalan, 1
document.body.append(document.createElement('div'));
alert(divs.length); // hali ham 1 (o'zgarmaydi)
querySelectorAll) xatti-harakat oldindan aytiluvchan bo'lgani uchun qulayroq.elemA.contains(elemB)
Yana bir foydali metod โ elemA.contains(elemB). U elemB elemA ichida (uning avlodi) yoki elemA === elemB bo'lsa, true qaytaradi:
// tekshirish: parent element child'ni o'z ichiga oladimi?
if (parentElem.contains(childElem)) {
alert('child parent ichida');
}
Barcha 6 metod umumiy jadval
Qidiruv metodlarini eslab qolish uchun umumiy ko'rinish:
querySelectorโ CSS-selektor, ilk element, istalgan element ustida ishlaydi;querySelectorAllโ CSS-selektor, statik to'plam;getElementByIdโidbo'yicha, faqatdocumentda;getElementsByNameโnamebo'yicha, faqatdocumentda, jonli;getElementsByTagNameโ teg yoki"*"bo'yicha, jonli;getElementsByClassNameโ klass bo'yicha, jonli.
querySelector va querySelectorAll yetarli. Ular eng moslashuvchan va yodda tutish oson. getElementById esa juda tez bo'lgani va oddiyligi tufayli id bo'yicha qidirishda hali ham ommabop.Xulosa
- 6 ta asosiy qidiruv metodi bor:
querySelector,querySelectorAll,getElementById,getElementsByName,getElementsByTagName,getElementsByClassName; getElementsBy*jonli (live) to'plam,querySelectorAllesa statik to'plam qaytaradi;elem.matches(css)โ element selektorga mosligini tekshiradi;elem.closest(css)โ selektorga mos eng yaqin ajdodni (o'zini ham) qidiradi;elemA.contains(elemB)โelemBelemAichida ekanligini tekshiradi.