DOM tugunlariga chuqurroq nazar tashlaylik.
Ushbu bobda biz ular nima ekanligini koârib chiqamiz va eng koâp ishlatiladigan xususiyatlarini oârganamiz.
DOM tugun klasslari
Turli DOM tugunlari turli xususiyatlarga ega boâlishi mumkin. Masalan, <a> tegiga mos keladigan element tuguni havola bilan bogâliq xususiyatlarga ega, <input> ga mos keluvchisi esa input bilan bogâliq xususiyatlarga ega va hokazo. Matn tugunlari element tugunlari bilan bir xil emas. Lekin ular orasida umumiy xususiyatlar va metodlar ham mavjud, chunki barcha DOM tugun klasslari yagona ierarxiyani tashkil qiladi.
Har bir DOM tuguni tegishli oârnatilgan klassga tegishli.
Ierarxiyaning ildizi EventTarget boâlib, undan Node meros oladi va boshqa DOM tugunlari undan meros oladi.
Mana rasm, tushuntirishlar keyinroq:
Klasslar:
- EventTarget â ildiz âmavhumâ klass. Bu klassning obyektlari hech qachon yaratilmaydi. U asos boâlib xizmat qiladi, shunda barcha DOM tugunlari âhodisalarâ deb ataladigan narsani qoâllab-quvvatlaydi, biz ularni keyinroq oârganamiz.
- Node â bu ham âmavhumâ klass boâlib, DOM tugunlari uchun asos boâlib xizmat qiladi. U asosiy daraxt funksionalligini taqdim etadi:
parentNode,nextSibling,childNodesva hokazo (bular getterâlardir).Nodeklassining obyektlari hech qachon yaratilmaydi. Lekin undan meros oladigan aniq tugun klasslari mavjud, yaâni: matn tugunlari uchunText, element tugunlari uchunElementva izoh tugunlari uchunCommentkabi boshqa ekzotik klasslar. - Element â DOM elementlari uchun asos klass. U element darajasidagi navigatsiyani taqdim etadi, masalan
nextElementSibling,childrenvagetElementsByTagName,querySelectorkabi qidiruv metodlari. Brauzer nafaqat HTML, balki XML va SVG ni ham qoâllab-quvvatlaydi.Elementklassi aniqroq klasslar uchun asos boâlib xizmat qiladi:SVGElement,XMLElementvaHTMLElement. - HTMLElement â nihoyat barcha HTML elementlari uchun asosiy klass. Undan aniq HTML elementlari meros oladi:
- HTMLInputElement â
<input>elementlari uchun klass, - HTMLBodyElement â
<body>elementlari uchun klass, - HTMLAnchorElement â
<a>elementlari uchun klass, - â¦va hokazo, har bir tegning aniq xususiyatlar va metodlarni taqdim etishi mumkin boâlgan oâz klassi bor.
- HTMLInputElement â
Shunday qilib, berilgan tugunning barcha xususiyatlar va metodlari toâplami merosxoârlik natijasida hosil boâladi.
Masalan, <input> element uchun DOM obyektini koârib chiqaylik. U HTMLInputElement klassiga tegishli.
U xususiyatlar va metodlarni quyidagi klasslardan superpozitsiya sifatida oladi (merosxoârlik tartibida):
HTMLInputElementâ bu klass input-ga xos xususiyatlarni taqdim etadi,HTMLElementâ umumiy HTML element metodlarini (va getter/setterâlarni) taqdim etadi,Elementâ umumiy element metodlarini taqdim etadi,Nodeâ umumiy DOM tugun xususiyatlarini taqdim etadi,EventTargetâ hodisalar uchun qoâllab-quvvatlash beradi (keyinroq yoritiladi),- â¦va nihoyat u
Objectdan meros oladi, shuning uchunhasOwnPropertykabi âoddiy obyektâ metodlari ham mavjud.
DOM tugun klass nomini koârish uchun, obyektda odatda constructor xususiyati borligini eslaymiz. U klass konstruktoriga havola qiladi va constructor.name uning nomi:
alert( document.body.constructor.name ); // HTMLBodyElement
â¦Yoki shunchaki uni toString qilishimiz mumkin:
alert( document.body ); // [object HTMLBodyElement]
Merosxoârlikni tekshirish uchun instanceof dan ham foydalanishimiz mumkin:
alert( document.body instanceof HTMLBodyElement ); // true
alert( document.body instanceof HTMLElement ); // true
alert( document.body instanceof Element ); // true
alert( document.body instanceof Node ); // true
alert( document.body instanceof EventTarget ); // true
Koârib turganingizdek, DOM tugunlari oddiy JavaScript obyektlaridir. Ular merosxoârlik uchun prototipga asoslangan klasslardan foydalanadilar.
Buni brauzerdagi console.dir(elem) yordamida elementni chiqarish orqali ham osongina koârish mumkin. Konsolda siz HTMLElement.prototype, Element.prototype va hokazolarni koârishingiz mumkin.
console.dir(elem) va console.log(elem) farqiKoâpgina brauzerlar oâzlarining dasturchi vositalarida ikkita buyruqni qoâllab-quvvatlaydi: console.log va console.dir. Ular oâz argumentlarini konsolga chiqaradi. JavaScript obyektlari uchun bu buyruqlar odatda bir xil ish qiladi.
Lekin DOM elementlari uchun ular boshqacha:
console.log(elem)element DOM daraxtini koârsatadi.console.dir(elem)elementni DOM obyekti sifatida koârsatadi, uning xususiyatlarini oârganish uchun yaxshi.
Buni document.body da sinab koâring.
Spetsifikatsiyada DOM klasslari JavaScript yordamida emas, balki maxsus Interface description language (IDL) yordamida tasvirlangan, bu odatda tushunish oson.
IDL da barcha xususiyatlar oâz turlari bilan boshlanadi. Masalan, DOMString, boolean va hokazo.
Mana undan parcha, izohlar bilan:
// HTMLInputElement ni belgilash
// ":" belgisi HTMLInputElement HTMLElement dan meros olishini anglatadi
interface HTMLInputElement: HTMLElement {
// bu yerda <input> elementlarining xususiyatlari va metodlari keladi
// "DOMString" xususiyat qiymati satr ekanligini anglatadi
attribute DOMString accept;
attribute DOMString alt;
attribute DOMString autocomplete;
attribute DOMString value;
// boolean qiymat xususiyati (true/false)
attribute boolean autofocus;
...
// endi metod: "void" metod hech qanday qiymat qaytarmasligini anglatadi
void select();
...
}
ânodeTypeâ xususiyati
nodeType xususiyati DOM tugunining âturiniâ olishning yana bir âeski uslubâ usulini taqdim etadi.
Unda raqamli qiymat bor:
elem.nodeType == 1element tugunlari uchun,elem.nodeType == 3matn tugunlari uchun,elem.nodeType == 9hujjat obyekti uchun,- spetsifikatsiyada bir nechta boshqa qiymatlar mavjud.
Masalan:
<body>
<script>
let elem = document.body;
// bu nima ekanligini tekshiraylik?
alert(elem.nodeType); // 1 => element
// va birinchi bola bu...
alert(elem.firstChild.nodeType); // 3 => matn
// hujjat obyekti uchun tur 9
alert( document.nodeType ); // 9
</script>
</body>
Zamonaviy skriptlarda biz tugun turini koârish uchun instanceof va boshqa klassga asoslangan testlardan foydalanishimiz mumkin, lekin baâzan nodeType soddaroq boâlishi mumkin. Biz nodeType ni faqat oâqishimiz mumkin, oâzgartira olmaymiz.
Teg: nodeName va tagName
DOM tugun berilgan boâlsa, uning teg nomini nodeName yoki tagName xususiyatlaridan oâqishimiz mumkin:
Masalan:
alert( document.body.nodeName ); // BODY
alert( document.body.tagName ); // BODY
tagName va nodeName orasida farq bormi?
Albatta, farq ularning nomlarida aks etgan, lekin haqiqatan ham biroz nozik.
tagNamexususiyati faqatElementtugunlari uchun mavjud.nodeNamehar qandayNodeuchun belgilangan:- elementlar uchun u
tagNamebilan bir xil maânoni anglatadi. - boshqa tugun turlari uchun (matn, izoh va hokazo) unda tugun turi bilan satr bor.
- elementlar uchun u
Boshqacha qilib aytganda, tagName faqat element tugunlari tomonidan qoâllab-quvvatlanadi (Element klassidan kelib chiqqani uchun), nodeName esa boshqa tugun turlari haqida ham nimadir aytishi mumkin.
Masalan, document va izoh tuguni uchun tagName va nodeName ni taqqoslaylik:
<body><!-- izoh -->
<script>
// izoh uchun
alert( document.body.firstChild.tagName ); // undefined (element emas)
alert( document.body.firstChild.nodeName ); // #comment
// hujjat uchun
alert( document.tagName ); // undefined (element emas)
alert( document.nodeName ); // #document
</script>
</body>
Agar biz faqat elementlar bilan ishlasak, tagName va nodeName dan foydalanishimiz mumkin â farq yoâq.
Brauzer hujjatlarni qayta ishlashning ikkita rejimiga ega: HTML va XML. Odatda veb-sahifalar uchun HTML rejimi ishlatiladi. XML rejimi brauzer XML-hujjatni quyidagi sarlavha bilan olganda yoqiladi: Content-Type: application/xml+xhtml.
HTML rejimida tagName/nodeName har doim katta harfda: <body> yoki <BoDy> uchun BODY boâladi.
XML rejimida registr âoâz holatidaâ saqlanadi. Hozir XML rejimi kamdan-kam qoâllaniladi.
innerHTML: tarkib
innerHTML xususiyati element ichidagi HTML ni satr sifatida olish imkonini beradi.
Biz uni oâzgartirishimiz ham mumkin. Shuning uchun bu sahifani oâzgartirishning eng kuchli usullaridan biri.
Misol document.body ning tarkibini koârsatadi va keyin uni butunlay almashtiradi:
<body>
<p>Paragraf</p>
<div>Div</div>
<script>
alert( document.body.innerHTML ); // joriy tarkibni o'qish
document.body.innerHTML = 'Yangi BODY!'; // uni almashtirish
</script>
</body>
Notoâgâri HTML kiritishga harakat qilishimiz mumkin, brauzer bizning xatolarimizni tuzatadi:
<body>
<script>
document.body.innerHTML = '<b>test'; // tegni yopishni unutdik
alert( document.body.innerHTML ); // <b>test</b> (tuzatildi)
</script>
</body>
Agar innerHTML hujjatga <script> tegini kiritsa â u HTML ning bir qismi boâladi, lekin bajarilmaydi.
Ehtiyot boâling: âinnerHTML+=â toâliq qayta yozishni amalga oshiradi
Biz elem.innerHTML+="ko'proq html" dan foydalanib elementga HTML qoâshishimiz mumkin.
Quyidagicha:
chatDiv.innerHTML += "<div>Salom<img src='smile.gif'/> !</div>";
chatDiv.innerHTML += "Qanday hollar?";
Lekin buni qilishda juda ehtiyot boâlishimiz kerak, chunki sodir boâlayotgan narsa qoâshish emas, balki toâliq qayta yozish.
Texnik jihatdan, bu ikki qator bir xil ish qiladi:
elem.innerHTML += "...";
// quyidagini yozishning qisqaroq usuli:
elem.innerHTML = elem.innerHTML + "..."
Boshqacha qilib aytganda, innerHTML+= quyidagilarni qiladi:
- Eski tarkib olib tashlanadi.
- Yangi
innerHTMLuning oârniga yoziladi (eskisi va yangisining birlashtmasi).
Tarkib ânolga aylantirilganiâ va noldan qayta yozilgani uchun, barcha rasmlar va boshqa resurslar qayta yuklanadi.
Yuqoridagi chatDiv misolida chatDiv.innerHTML+="Qanday hollar?" qatori HTML tarkibini qayta yaratadi va smile.gif ni qayta yuklaydi (umid qilamanki, u keshda). Agar chatDiv da koâp boshqa matn va rasmlar boâlsa, qayta yuklash aniq koârinadi.
Boshqa nojoâya taâsirlar ham bor. Masalan, agar mavjud matn sichqoncha bilan tanlangan boâlsa, koâpgina brauzerlar innerHTML ni qayta yozishda tanlovni olib tashlaydi. Va agar tashrif buyuruvchi tomonidan matn kiritilgan <input> boâlsa, matn olib tashlanadi. Va hokazo.
Yaxshiyamki, innerHTMLdan tashqari HTML qoâshishning boshqa usullari ham bor va biz ularni tez orada oârganamiz.
outerHTML: elementning toâliq HTML i
outerHTML xususiyati elementning toâliq HTML ini oâz ichiga oladi. Bu innerHTML plus elementning oâzi kabi.
Mana misol:
<div id="elem">Salom <b>Dunyo</b></div>
<script>
alert(elem.outerHTML); // <div id="elem">Salom <b>Dunyo</b></div>
</script>
Ehtiyot boâling: innerHTMLdan farqli oâlaroq, outerHTMLga yozish elementni oâzgartirmaydi. Buning oârniga, uni DOM da almashtiradi.
Ha, gâalati eshitiladi va gâalati, shuning uchun biz bu haqida alohida eslatma qilamiz. Qarang.
Misolni koârib chiqing:
<div>Salom, dunyo!</div>
<script>
let div = document.querySelector('div');
// div.outerHTML ni <p>...</p> bilan almashtirish
div.outerHTML = '<p>Yangi element</p>'; // (*)
// Voy! 'div' hali ham bir xil!
alert(div.outerHTML); // <div>Salom, dunyo!</div> (**)
</script>
Haqiqatan ham gâalati koârinadi, shunday emasmi?
(*) qatorida biz div ni <p>Yangi element</p> bilan almashtirdik. Tashqi hujjatda (DOM da) biz <div> oârniga yangi tarkibni koârishimiz mumkin. Lekin (**) qatorida koârib turganingizdek, eski div oâzgaruvchisining qiymati oâzgarmagan!
outerHTML tayinlashi DOM elementni (bu holda âdivâ oâzgaruvchisi tomonidan havola qilingan obyektni) oâzgartirmaydi, balki uni DOM dan olib tashlaydi va uning oârniga yangi HTML ni kiritadi.
Shunday qilib, div.outerHTML=... da sodir boâlgan narsa:
divhujjatdan olib tashlandi.- Boshqa HTML qismi
<p>Yangi element</p>uning oârniga kiritildi. divhali ham eski qiymatiga ega. Yangi HTML hech qanday oâzgaruvchiga saqlanmadi.
Bu yerda xato qilish juda oson: div.outerHTML ni oâzgartirish va keyin div bilan xuddi unda yangi tarkib bor kabi ishlashni davom ettirish. Lekin bunday emas. Bunday narsa innerHTML uchun toâgâri, lekin outerHTML uchun emas.
Biz elem.outerHTML ga yozishimiz mumkin, lekin yozayotgan elementni (âelemâ) oâzgartirmasligini yodda tutishimiz kerak. Buning oârniga yangi HTML ni uning oârniga qoâyadi. DOM ni soârab yangi elementlarga havolalar olishimiz mumkin.
nodeValue/data: matn tuguni tarkibi
innerHTML xususiyati faqat element tugunlari uchun amal qiladi.
Boshqa tugun turlari, masalan matn tugunlari, oâzlarining hamkasbi bor: nodeValue va data xususiyatlari. Bu ikkitasi amaliy foydalanish uchun deyarli bir xil, faqat kichik spetsifikatsiya farqlari bor. Shuning uchun biz data dan foydalanamiz, chunki u qisqaroq.
Matn tuguni va izoh tarkibini oâqish misoli:
<body>
Salom
<!-- Izoh -->
<script>
let text = document.body.firstChild;
alert(text.data); // Salom
let comment = text.nextSibling;
alert(comment.data); // Izoh
</script>
</body>
Matn tugunlari uchun ularni oâqish yoki oâzgartirishning sababini tasavvur qilishimiz mumkin, lekin izohlar nima uchun?
Baâzan dasturchilar HTML ga maâlumot yoki shablon koârsatmalarini quyidagicha joylashtiradilar:
<!-- agar isAdmin -->
<div>Xush kelibsiz, Admin!</div>
<!-- /if -->
â¦Keyin JavaScript uni data xususiyatidan oâqib, joylashtirilgan koârsatmalarni qayta ishlashi mumkin.
textContent: sof matn
textContent element ichidagi matnga kirish imkonini beradi: faqat matn, barcha <tags>siz.
Masalan:
<div id="news">
<h1>Sarlavha!</h1>
<p>Marsliklar odamlarga hujum qilmoqda!</p>
</div>
<script>
// Sarlavha! Marsliklar odamlarga hujum qilmoqda!
alert(news.textContent);
</script>
Koârib turganingizdek, faqat matn qaytariladi, xuddi barcha <tags> kesilgan, lekin ulardagi matn qolgan kabi.
Amaliyotda bunday matnni oâqish kamdan-kam kerak boâladi.
textContentga yozish ancha foydali, chunki u matnni âxavfsiz usuldaâ yozish imkonini beradi.
Aytaylik, bizda ixtiyoriy satr bor, masalan foydalanuvchi tomonidan kiritilgan va uni koârsatishni xohlaymiz.
innerHTMLbilan u âHTML sifatidaâ kiritiladi, barcha HTML teglari bilan.textContentbilan u âmatn sifatidaâ kiritiladi, barcha belgilar tom maânoda qabul qilinadi.
Ikkitasini taqqoslang:
<div id="elem1"></div>
<div id="elem2"></div>
<script>
let name = prompt("Ismingiz nima?", "<b>Vinni-Pux!</b>");
elem1.innerHTML = name;
elem2.textContent = name;
</script>
- Birinchi
<div>ismni âHTML sifatidaâ oladi: barcha teglar tegga aylanadi, shuning uchun biz qalin ismni koâramiz. - Ikkinchi
<div>ismni âmatn sifatidaâ oladi, shuning uchun biz tom maânoda<b>Vinni-Pux!</b>ni koâramiz.
Koâpgina hollarda biz foydalanuvchidan matn kutamiz va uni matn sifatida koârishni xohlaymiz. Biz saytimizda kutilmagan HTML ni xohlamaymiz. textContentga tayinlash aynan shuni qiladi.
âhiddenâ xususiyati
âhiddenâ atributi va DOM xususiyati element koârinadimi yoki yoâqmi belgilaydi.
Biz uni HTML da ishlatishimiz yoki JavaScript yordamida tayinlashimiz mumkin, quyidagicha:
<div>Quyidagi ikkala div ham yashiringan</div>
<div hidden>"hidden" atributi bilan</div>
<div id="elem">JavaScript "hidden" xususiyatini tayinladi</div>
<script>
elem.hidden = true;
</script>
Texnik jihatdan, hidden style="display:none" bilan bir xil ishlaydi. Lekin yozish uchun qisqaroq.
Mana miltillovchi element:
<div id="elem">Miltillovchi element</div>
<script>
setInterval(() => elem.hidden = !elem.hidden, 1000);
</script>
Koâproq xususiyatlar
DOM elementlari qoâshimcha xususiyatlarga ham ega, xususan klassga bogâliq boâlganlar:
valueâ<input>,<select>va<textarea>uchun qiymat (HTMLInputElement,HTMLSelectElementâ¦).hrefâ<a href="...">uchun âhrefâ (HTMLAnchorElement).idâ barcha elementlar uchun âidâ atributining qiymati (HTMLElement).- â¦va boshqa koâp narsalarâ¦
Masalan:
<input type="text" id="elem" value="qiymat">
<script>
alert(elem.type); // "text"
alert(elem.id); // "elem"
alert(elem.value); // qiymat
</script>
Koâpgina standart HTML atributlari tegishli DOM xususiyatiga ega va biz unga shunday murojaat qilishimiz mumkin.
Agar berilgan klass uchun qoâllab-quvvatlanadigan xususiyatlarning toâliq roâyxatini bilishni istasak, ularni spetsifikatsiyada topishimiz mumkin. Masalan, HTMLInputElement https://html.spec.whatwg.org/#htmlinputelement da hujjatlashtirilgan.
Yoki agar ularni tez olishni istasak yoki aniq brauzer spetsifikatsiyasiga qiziqsak â biz har doim console.dir(elem) yordamida elementni chiqarib, xususiyatlarni oâqishimiz mumkin. Yoki brauzer dasturchi vositalarining Elements tabidagi âDOM propertiesâ ni oârganishimiz mumkin.
Xulosa
Har bir DOM tuguni maâlum bir klassga tegishli. Klasslar ierarxiya tashkil qiladi. Toâliq xususiyatlar va metodlar toâplami merosxoârlik natijasida keladi.
Asosiy DOM tugun xususiyatlari:
nodeType- Uni tugun matn yoki element tuguni ekanligini koârish uchun ishlatishimiz mumkin. Unda raqamli qiymat bor: elementlar uchun
1, matn tugunlari uchun3va boshqa tugun turlari uchun bir nechta boshqalar. Faqat oâqish. nodeName/tagName- Elementlar uchun teg nomi (XML rejimdan tashqari katta harfda). Element boâlmagan tugunlar uchun
nodeNameu nima ekanligini tasvirlaydi. Faqat oâqish. innerHTML- Elementning HTML tarkibi. Oâzgartirilishi mumkin.
outerHTML- Elementning toâliq HTML i.
elem.outerHTMLga yozish operatsiyasielemning oâziga tegmaydi. Buning oârniga u tashqi kontekstda yangi HTML bilan almashtiriladi. nodeValue/data- Element boâlmagan tugunning tarkibi (matn, izoh). Bu ikkitasi deyarli bir xil, odatda biz
datadan foydalanamiz. Oâzgartirilishi mumkin. textContent- Element ichidagi matn: HTML minus barcha
<tags>. Unga yozish matnni element ichiga qoâyadi, barcha maxsus belgilar va teglar aniq matn sifatida qaraladi. Foydalanuvchi tomonidan yaratilgan matnni xavfsiz kiritish va kiritmagan HTML dan himoyalash mumkin. hiddentruega oârnatilganda, CSSdisplay:nonebilan bir xil ish qiladi.
DOM tugunlari oâz klassiga qarab boshqa xususiyatlarga ham ega. Masalan, <input> elementlari (HTMLInputElement) value, type ni qoâllab-quvvatlaydi, <a> elementlari (HTMLAnchorElement) esa href va hokazolarni qoâllab-quvvatlaydi. Koâpgina standart HTML atributlari tegishli DOM xususiyatiga ega.
Biroq, HTML atributlari va DOM xususiyatlari har doim bir xil emas, buni keyingi bobda koâramiz.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)