Shadow DOM inkapsulyatsiya uchun xizmat qiladi. U komponentga oâzining âsoyaâ DOM daraxtiga ega boâlish imkonini beradi, unga asosiy hujjatdan tasodifan kirish mumkin emas, mahalliy uslub qoidalari boâlishi mumkin va boshqalar.
Oârnatilgan shadow DOM
Siz hech qachon murakkab brauzer boshqaruv elementlari qanday yaratilishi va shakllantirilanishi haqida oâylab koârganmisiz?
Masalan <input type="range">:
Brauzer ularni chizish uchun ichkarida DOM/CSS dan foydalanadi. Bu DOM tuzilmasi odatda bizdan yashiringan, lekin biz uni dasturchi vositalarida koârishimiz mumkin. Masalan, Chrome da biz Dev Tools da âShow user agent shadow DOMâ opsiyasini yoqishimiz kerak.
Keyin <input type="range"> quyidagicha koârinadi:
#shadow-root ostida koârayotgan narsa âshadow DOMâ deb ataladi.
Biz oârnatilgan shadow DOM elementlarini oddiy JavaScript chaqiruvlari yoki selektorlar orqali ola olmaymiz. Bular oddiy bolalar emas, balki kuchli inkapsulyatsiya texnikasi.
Yuqoridagi misolda biz foydali pseudo atributini koârishimiz mumkin. Bu nostandart, tarixiy sabablarga koâra mavjud. Biz uni CSS bilan subelementlarni shakllantirish uchun ishlatishimiz mumkin:
<style>
/* slayder yo'lini qizil qiling */
input::-webkit-slider-runnable-track {
background: red;
}
</style>
<input type="range">
Yana bir bor, pseudo nostandart atribut. Xronologik jihatdan, brauzerlar avval boshqaruv elementlarini amalga oshirish uchun ichki DOM tuzilmalari bilan tajriba qila boshladilar va keyin vaqt oâtgach, shadow DOM standartlashtirildi, bizga, dasturchilarga xuddi shunday ishni qilish imkonini berish uchun.
Bundan keyin biz DOM spec va boshqa tegishli spetsifikatsiyalar tomonidan qamrab olingan zamonaviy shadow DOM standartidan foydalanamiz.
Shadow darakti
DOM elementi ikkita turdagi DOM subdaraxtlariga ega boâlishi mumkin:
- Light tree â HTML bolalardan tuzilgan oddiy DOM subdaxti. Oldingi boblarda koârgan barcha subdaxtlar âlightâ edi.
- Shadow tree â yashirin DOM subdaxti, HTML da aks etmaydi, koâzlardan yashiringan.
Agar elementda ikkalasi ham boâlsa, brauzer faqat shadow daraxtini render qiladi. Lekin biz shadow va light daxtlar oârtasida qandaydir kompozitsiya ham oârnatishimiz mumkin. Tafsilotlarni keyinroq Shadow DOM slotlar, kompozitsiya bobida koâramiz.
Shadow tree Custom Elements da komponent ichki qismlarini yashirish va komponent-mahalliy uslublarni qoâllash uchun ishlatilishi mumkin.
Masalan, bu <show-hello> elementi oâzining ichki DOM ini shadow tree da yashiradi:
<script>
customElements.define('show-hello', class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = `<p>
Salom, ${this.getAttribute('name')}
</p>`;
}
});
</script>
<show-hello name="John"></show-hello>
Chrome dev tools da natijada paydo boâlgan DOM quyidagicha koârinadi, barcha kontent â#shadow-rootâ ostida:
Birinchi, elem.attachShadow({mode: â¦}) ga chaqiruv shadow daraxtini yaratadi.
Ikkita cheklov bor:
- Biz har bir element uchun faqat bitta shadow root yaratishimiz mumkin.
elemcustom element yoki quyidagilardan biri boâlishi kerak: âarticleâ, âasideâ, âblockquoteâ, âbodyâ, âdivâ, âfooterâ, âh1â¦h6â, âheaderâ, âmainâ ânavâ, âpâ, âsectionâ, yoki âspanâ. Boshqa elementlar, masalan<img>, shadow tree ni joylashtirib boâlmaydi.
mode opsiyasi inkapsulyatsiya darajasini belgilaydi. U ikkita qiymatdan birini olishi kerak:
-
"open"â shadow rootelem.shadowRootsifatida mavjud.Har qanday kod
elemning shadow tree ga kirishga qodir. -
"closed"âelem.shadowRoothar doimnull.Biz shadow DOM ga faqat
attachShadowtomonidan qaytarilgan havola orqali kirishimiz mumkin (va ehtimol klass ichida yashiringan). Brauzer-mahalliy shadow daxtlari, masalan<input type="range">, yopiq. Ularga kirish yoâli yoâq.
attachShadow tomonidan qaytarilgan shadow root element kabi: biz uni toâldirish uchun innerHTML yoki append kabi DOM metodlaridan foydalanishimiz mumkin.
Shadow root ga ega element âshadow tree hostâ deb ataladi va shadow root host xususiyati sifatida mavjud:
// {mode: "open"} deb faraz qilsak, aks holda elem.shadowRoot null
alert(elem.shadowRoot.host === elem); // true
Inkapsulyatsiya
Shadow DOM asosiy hujjatdan qattiq ajratilgan:
- Shadow DOM elementlari light DOM dan
querySelectoruchun koârinmaydi. Xususan, Shadow DOM elementlarida light DOM dagi bilan toâqnashadigan id lar boâlishi mumkin. Ular faqat shadow tree ichida noyob boâlishi kerak. - Shadow DOM oâz stylesheetlariga ega. Tashqi DOM dan uslub qoidalari qoâllanilmaydi.
Masalan:
<style>
/* hujjat uslubi #elem ichidagi shadow tree ga qo'llanilmaydi (1) */
p { color: red; }
</style>
<div id="elem"></div>
<script>
elem.attachShadow({mode: 'open'});
// shadow tree o'z uslubiga ega (2)
elem.shadowRoot.innerHTML = `
<style> p { font-weight: bold; } </style>
<p>Salom, John!</p>
`;
// <p> faqat shadow tree ichidagi so'rovlardan ko'rinadi (3)
alert(document.querySelectorAll('p').length); // 0
alert(elem.shadowRoot.querySelectorAll('p').length); // 1
</script>
- Hujjatdagi uslub shadow tree ga taâsir qilmaydi.
- â¦Lekin ichkaridagi uslub ishlaydi.
- Shadow tree dagi elementlarni olish uchun biz daraxt ichidan soârov qilishimiz kerak.
Manbalar
- DOM: https://dom.spec.whatwg.org/#shadow-trees
- Muvofiqlik: https://caniuse.com/#feat=shadowdomv1
- Shadow DOM koâplab boshqa spetsifikatsiyalarda ham eslatib oâtiladi, masalan DOM Parsing shadow root
innerHTMLga ega ekanligini belgilaydi.
Xulosa
Shadow DOM komponent-mahalliy DOM yaratish usuli.
shadowRoot = elem.attachShadow({mode: open|closed})âelemuchun shadow DOM yaratadi. Agarmode="open"boâlsa, uelem.shadowRootxususiyati sifatida mavjud.- Biz
shadowRootniinnerHTMLyoki boshqa DOM metodlar yordamida toâldirishimiz mumkin.
Shadow DOM elementlari:
- Oâz id makoniga ega,
- Asosiy hujjatdan JavaScript selektorlari, masalan
querySelectoruchun koârinmaydi, - Asosiy hujjatdan emas, faqat shadow tree dan uslublarni ishlatadi.
Shadow DOM, agar mavjud boâlsa, âlight DOMâ (oddiy bolalar) deb ataladigan narsaning oârniga brauzer tomonidan render qilinadi. Shadow DOM slotlar, kompozitsiya bobida biz ularni qanday birlashtirish mumkinligini 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â¦)