IlmHamroh
JavaScript Full-stack/4-qism. HTML80/86-dars14 daqiqa
Mundarija (27)

HTML template va slot: ko'rinmas qolip va Web Components uchun joy

Qisqacha: template — sahifada ko'rinmaydigan va ishlamaydigan HTML qolip. Brauzer uni o'qiydi, lekin chizmaydi: ichidagi rasm yuklanmaydi, skript ishlamaydi. Keyin JavaScript undan nusxa olib, ma'lumot bilan to'ldiradi va sahifaga qo'yadi. slot esa Web Component (o'zingiz yaratgan HTML teg) ichidagi bo'sh joy: tegdan foydalanuvchi o'z kontentini shu joyga joylaydi.

Bu darsda

  • template nima uchun kerakligini va "inert" so'zi nimani anglatishini tushuntira olasiz.
  • template ning yashirin div dan beshta farqini bilasiz.
  • JavaScript qolipdan qanday foydalanishini g'oya darajasida tushunasiz.
  • Nomli va standart slot, zaxira kontent qanday ishlashini ko'rsata olasiz.
  • "template" so'zining kursda uchraydigan turli ma'nolarini ajrata olasiz.

Oldin bilishingiz kerak: Fokus va tahrir atributlari, Kontent modeli, Brauzer HTML'ni qanday tahlil qiladi, Jadval asoslari.

1. Nega bu kerak?

O'tgan darslarda «Bahor» saytini accessibility bo'yicha tekshirib chiqdik. Endi sayt o'sayapti: menyuda 40 ta taom bor va narxlar tez-tez o'zgaradi. Jasur aka har safar HTML faylni qo'lda tahrirlashdan charchadi.

Keyinroq, JavaScript qismida, menyuni serverdan olib, jadvalni avtomatik chizishni o'rganamiz. Server faqat ma'lumot beradi: "Osh — 35 000", "Lag'mon — 28 000". Jadval qatorining HTML ko'rinishini esa kimdir oldindan tayyorlab qo'yishi kerak. Qatorda qaysi kataklar bor, qaysi class lar turadi — shu tuzilma bir marta yoziladi va 40 marta ishlatiladi.

Bu tuzilmani qayerda saqlash kerak? Sahifaning o'zida, lekin ko'rinmaydigan va ishlamaydigan holda. Buning uchun HTML'da maxsus teg bor — template.

Pishiriq qolipini tasavvur qiling. Qolipning o'zi yeyilmaydi — u ovqat emas. Lekin unga xamir solsangiz, har safar bir xil shakldagi pishiriq chiqadi. template — HTML uchun shunday qolip.

2. template — ko'rinmas qolip

2.1 Birinchi misol

«Bahor» menyu jadvali uchun bitta qator qolipi:

html
<table>
  <caption>Menyu</caption>
  <thead>
    <tr>
      <th scope="col">Taom</th>
      <th scope="col">Narxi (so'm)</th>
    </tr>
  </thead>
  <tbody id="menyu-qatorlar">
  </tbody>
</table>

<template id="taom-qolip">
  <tr>
    <td class="nomi"></td>
    <td class="narxi"></td>
  </tr>
</template>

Brauzerda faqat bo'sh jadval sarlavhasi ko'rinadi. template ichidagi qator — yo'q. Go'yo uni umuman yozmagandek.

Endi F12 → Elements panelini oching. template ni oching — ichida #document-fragment degan yozuv turadi, uning ichida esa bizning tr. Document fragment (hujjat bo'lagi) — asosiy sahifaga ulanmagan, alohida turgan kichik HTML bo'lak. Brauzer qolipni o'qib, shu bo'lakka joylagan. Sahifaning o'ziga emas.

2.2 "Inert" nima degani

template ichidagi kontent inert — ya'ni "harakatsiz", "uxlab yotgan". Biz buni headless Chrome'da sinab ko'rdik (qolip ichiga rasm, skript va forma maydoni qo'yib):

Qolip ichida Nima bo'ladi
Matn va teglar Ekranda ko'rinmaydi
img src="..." Rasm yuklanmaydi — Network panelida so'rov yo'q
script Ishlamaydi
input Forma bilan yuborilmaydi
id="ichki" Sahifadan qidirilganda topilmaydi

Qolipdagi rasm ham, skript ham faqat JavaScript nusxani sahifaga qo'ygan paytda "uyg'onadi". Qolip bir marta yuklangan sahifada tursa ham, trafik yemaydi va hech narsani buzmaydi.

Tekshirib ko'ring: Qolip ichida <img src="osh.jpg" alt=""> bor. Sahifa ochilganda osh.jpg yuklanadimi?

Javob

Yo'q. template kontenti inert — brauzer uni tahlil qiladi, lekin rasm uchun so'rov yubormaydi. Rasm faqat JavaScript qolip nusxasini sahifaga qo'shganda yuklanadi. DevTools Network panelida buni tekshirish mumkin.

3. Nega yashirin div emas?

"Qolipni hidden atributli div ga yozsam bo'lmaydimi? U ham ko'rinmaydi-ku." Sinab ko'ramiz. Xuddi shu kontentni div hidden ichiga qo'ydik:

html
<!-- ❌ qolip sifatida -->
<div hidden>
  <img src="assets/images/osh.jpg" alt="">
  <input type="text" name="taom" value="osh">
</div>

Natija headless Chrome'da:

  • Rasm yuklandi. hidden faqat ko'rsatmaydi, yuklashni to'xtatmaydi. 40 ta yashirin rasm — bekorga ketgan trafik.
  • Skript ishladi. Yashirin blok ichidagi script ham bajariladi.
  • Maydon forma bilan yuborildi. Forma ichidagi yashirin input serverga ketdi — template dagisi esa ketmadi.
  • id lar sahifada bor. Qolipdagi id sahifaning id lari bilan to'qnashadi.

Beshinchi farq eng qiziqarlisi. Jadval qatorini div ichiga yozib ko'ramiz:

html
<!-- ❌ -->
<div hidden id="qolip">
  <tr><td>osh</td></tr>
</div>

Brauzer bu div ichida faqat osh degan matnni qoldirdi. Jadval teglari — tr va td — yo'qoldi. Brauzer HTML'ni qanday tahlil qiladi darsidagi qoidani eslang: parser tr ni faqat jadval ichida qabul qiladi, boshqa joyda uni tashlab yuboradi.

template esa bu qoidadan ozod. Parser uning ichida istalgan elementni qabul qiladi — tr, li, option, hatto td ni ham. Qolip o'zi ham deyarli istalgan joyda tura oladi: head da, body da, hatto tbody, ul yoki select ning ichida. Bu joylarda boshqa teglarga ruxsat yo'q, lekin template ga bor. Standart uni alohida turkumga — "skriptni qo'llab-quvvatlovchi elementlar" (script-supporting elements) ga kiritgan. Kontent modeli darsidagi turkumlarni eslang: bu turkum elementlariga ko'p joyda ruxsat bor.

div hidden template
Ko'rinadimi Yo'q Yo'q
Rasm yuklanadimi Ha Yo'q
Skript ishlaydimi Ha Yo'q
Maydon yuboriladimi Ha Yo'q
tr ni saqlay oladimi Yo'q Ha

Tekshirib ko'ring: Nega div hidden ichidagi tr yo'qoladi, template ichidagisi esa qoladi?

Javob

Parser tr ni faqat jadval kontekstida qabul qiladi. Oddiy div ichida bu xato hisoblanadi va teg tashlab yuboriladi — faqat ichidagi matn qoladi. Qolip ichidagi kontent esa alohida hujjat bo'lagiga, maxsus qoidalar bilan tahlil qilinadi: u yerda tr ham, td ham o'z holicha saqlanadi.

4. JavaScript qolipdan qanday foydalanadi

JavaScript'ni hali o'rganmadik. Lekin template ning butun ma'nosi shu yerda. Shuning uchun kodni faqat g'oya sifatida, qatorma-qator ko'ramiz:

js
const qolip = document.querySelector("#taom-qolip");
const nusxa = qolip.content.cloneNode(true);
nusxa.querySelector(".nomi").textContent = "Osh";
nusxa.querySelector(".narxi").textContent = "35 000";
document.querySelector("#menyu-qatorlar").append(nusxa);
  1. id="taom-qolip" bo'lgan qolipni topamiz.
  2. content — qolip ichidagi hujjat bo'lagi. cloneNode(true) — undan to'liq nusxa olish. Qolipning o'zi o'zgarmaydi — keyingi taom uchun ham kerak.
  3. Nusxadagi .nomi katagiga matn yozamiz.
  4. .narxi katagiga — narx.
  5. Tayyor qatorni jadvalning tbody siga qo'shamiz. Shu lahzada qator ko'rinadi va "uyg'onadi".

40 ta taom uchun 2–5-qadamlar 40 marta takrorlanadi. HTML tuzilma esa bitta joyda — qolipda. Dizayner "narx ustuniga 'so'm' qo'shaylik" desa, faqat qolipni o'zgartirasiz.

Bu kodni to'liq Ko'p elementni samarali chizish darsida yozamiz. Hozir ikki narsani eslab qoling:

  • Qolipdagi elementlar class bilan belgilanadi, id bilan emas. Nima uchun — "Ko'p uchraydigan xatolar" bo'limida.
  • Matn textContent bilan yoziladi. Bu xavfsiz yo'l: taom nomida <script> bo'lsa ham, u oddiy matn bo'lib chiqadi. Nega bu muhimligini keyingi darsda — HTML darajasidagi xavfsizlik — ko'ramiz.

5. slot — komponent ichidagi bo'sh joy

5.1 Web Components haqida bir og'iz

Web Components — o'z HTML tegingizni yaratish texnologiyasi. Masalan, <taom-karta> tegi: uni yozsangiz, tayyor bezakli taom kartasi chiqadi. Uning ichki tuzilmasi va ko'rinishi Shadow DOM da yashiringan. Shadow DOM — tegning tashqaridan yopiq, alohida ichki qismi.

Bu texnologiyaning asosiy qismi JavaScript'da yoziladi. Uni Web Components'ga kirish va Web Components darslarida to'liq o'rganamiz. Hozir bilish shart emas — faqat slot qanday ishlashini tushunish uchun kerakli qismini ko'ramiz.

5.2 G'oya: blanka va to'ldiriladigan joylar

Taklifnoma blankasini eslang: "Hurmatli ______! Sizni ______ kuni to'yimizga taklif qilamiz." Blanka bosmaxonada tayyor — bezagi, shrifti, ramkasi. Bo'sh chiziqlarni esa har kim o'zi to'ldiradi.

Web Component — blanka. slot — bo'sh chiziq. Tegdan foydalanuvchi o'z kontentini shu joylarga qo'yadi.

5.3 JavaScript'siz ko'rib chiqamiz

Odatda Shadow DOM JavaScript bilan yaratiladi. Lekin 2024-yildan beri barcha asosiy brauzerlarda uni to'g'ridan-to'g'ri HTML'da yozish mumkin — template ga bitta atribut qo'shib. Bu usulning to'liq tafsilotlari Web Components'ga kirish darsida. Bu yerda uni faqat slot ni o'z ko'zingiz bilan ko'rish uchun ishlatamiz:

html
<taom-karta>
  <template shadowrootmode="open">
    <article>
      <h3><slot name="nomi">Nomsiz taom</slot></h3>
      <p>Narxi: <slot name="narxi">so'rang</slot></p>
      <slot>Tavsif yo'q.</slot>
    </article>
  </template>
  <span slot="nomi">Osh</span>
  <span slot="narxi">35 000 so'm</span>
  <p>Guruch, sabzi va mol go'shti, zig'ir yog'ida.</p>
</taom-karta>

Brauzerda:

text
Osh                                             ← h3
Narxi: 35 000 so'm
Guruch, sabzi va mol go'shti, zig'ir yog'ida.

Qatorma-qator:

  • taom-karta — o'zimiz o'ylab topgan teg. Nomida defis majburiy — shunda brauzer uni kelajakdagi standart teglardan ajratadi.
  • template shadowrootmode="open" — "bu qolipni shu tegning Shadow DOM'iga aylantir". Oddiy template kabi uxlab yotmaydi — brauzer uni sahifa tahlil qilinayotganda darhol ishlatadi.
  • <slot name="nomi"> — nomli slot: "bu yerga slot="nomi" atributli element keladi".
  • <span slot="nomi">Osh</span> — foydalanuvchining kontenti. slot atributi uni name="nomi" joyiga yuboradi.
  • <slot> (nomsiz) — standart slot: slot atributisiz hamma kontent shu yerga tushadi. Bizda — tavsif paragrafi.
  • Slot ichidagi matn ("Nomsiz taom", "so'rang") — zaxira kontent (fallback). Joyga hech narsa kelmasa, shu ko'rinadi.

5.4 Zaxira kontent amalda

Ikkinchi kartada narx yozilmagan:

html
<taom-karta>
  <template shadowrootmode="open">
    <article>
      <h3><slot name="nomi">Nomsiz taom</slot></h3>
      <p>Narxi: <slot name="narxi">so'rang</slot></p>
      <slot>Tavsif yo'q.</slot>
    </article>
  </template>
  <span slot="nomi">Kuzgi palov</span>
</taom-karta>

Brauzerda:

text
Kuzgi palov
Narxi: so'rang

narxi slotiga kontent kelmadi — zaxira matn "so'rang" ko'rindi. Lekin "Tavsif yo'q." ko'rinmadi. Nega? Axir tavsif ham berilmagan-ku.

Chrome'da tekshirib, sababini topdik. Standart slotga slot atributisiz hamma narsa tushadi — bo'sh joy va yangi qatorlar ham. taom-karta ichida teglar orasidagi chekinish (qatorlar boshidagi probellar) ham matn hisoblanadi. Standart slot shu "ko'rinmas matn"ni oldi va o'zini to'la deb hisobladi. Zaxira kontent esa faqat slot butunlay bo'sh bo'lganda chiqadi.

Xulosa: zaxira kontent nomli slotlarda ishonchli ishlaydi. Standart slotning zaxirasi esa faqat teg ichida hech narsa — hatto bo'sh joy ham — bo'lmaganda ko'rinadi. Bu — Web Components bilan ishlaganda ko'p dasturchini hayron qoldiradigan nozik joy.

Maslahat: Har kartada template ni takrorlash noqulay ekanini sezdingizmi? Real loyihada qolip bitta joyda yoziladi va JavaScript uni har taom-karta ga o'zi ulaydi. Shu darsdagi ikki g'oya — template va slot — aynan shu yerda birlashadi. HTML'dagi takrorlanadigan usul — faqat server sahifani tayyorlab yuborganda qulay.

5.5 Muhim nozikliklar

  • Kontent joyidan ko'chmaydi. <span slot="nomi">Osh</span> DOM'da hamon taom-karta ning bevosita farzandi. U faqat ko'rsatilishda slot joyiga "proyeksiya" qilinadi. Ekran o'quvchi ham uni ko'rinish tartibida — slot joyida — o'qiydi.
  • slot atributi faqat bevosita farzandda ishlaydi. <p><span slot="nomi">...</span></p> — ichkaridagi span nomli slotga bormaydi.
  • Shadow DOM'siz slot hech narsa qilmaydi. Oddiy sahifada <slot> qo'ysangiz, u shunchaki ichidagi zaxira matnni ko'rsatadi — o'zining qutisi ham bo'lmaydi.
  • Stil. Slotga tushgan kontentni komponent ichidan bezash — CSS'ning ::slotted() selektori bilan, Shadow DOM va web komponentlarni stillash darsida.

Tekshirib ko'ring: Quyidagi kontent qaysi slotlarga tushadi? <b slot="narxi">12 000</b>, <i>Achchiq-chuchuk</i>, <p slot="nomi">Salat</p>.

Javob

<b slot="narxi"> — name="narxi" slotiga. <p slot="nomi"> — name="nomi" slotiga. <i> da slot atributi yo'q — standart (nomsiz) slotga. Tartib ahamiyatsiz: element qayerda yozilganidan qat'i nazar, u o'z nomi bo'yicha joyini topadi.

6. "template" so'zining to'rt ma'nosi

Kursda "template" so'zini ko'p uchratasiz — va har safar boshqa narsa:

Qayerda Nima Qaysi darsda
HTML <template> tegi — inert qolip Shu dars
JavaScript Template literal — `Salom, ${ism}` satri Template literals
Server Shablon dvigateli (EJS, Handlebars) — serverda HTML yasash Backend qismi
Vue .vue fayldagi <template> bo'limi Frontend freymvorklar

Alpine.js va htmx kabi kichik kutubxonalar esa aynan HTML'dagi template tegini ishlatadi — masalan, ro'yxat qatori qolipi sifatida. Ular haqida freymvorklar qismida gaplashamiz.

7. Ko'p uchraydigan xatolar

7.1 Qolip ichidagi id

html
<!-- ❌ -->
<template id="taom-qolip">
  <tr>
    <td id="nomi"></td>
  </tr>
</template>

Qolip 40 marta klonlanadi — sahifada 40 ta id="nomi" paydo bo'ladi. id sahifada noyob bo'lishi shart (Global atributlar darsi). Tuzatish: qolip ichida class, qolipning o'zida esa id — uni topish uchun.

7.2 Qolip ichini sahifadan qidirish

JavaScript'da document.querySelector("#ichki") qolip ichidagi elementni topmaydi — natija null (bo'sh). Qolip kontenti sahifada emas, alohida hujjat bo'lagida. Tuzatish: avval qolip.content, keyin uning ichidan qidirish.

7.3 Yashirin div — qolip o'rnida

Rasm yuklanadi, skript ishlaydi, maydon yuboriladi, tr yo'qoladi. Tuzatish: qolip uchun faqat template.

7.4 Custom element nomida defis yo'q

html
<!-- ❌ -->
<taomkarta>
  <template shadowrootmode="open">
    <slot>Tavsif</slot>
  </template>
  Osh
</taomkarta>

Chrome konsolida shunday xabar chiqadi:

text
This element does not support attachShadow

Tarjimasi: "bu element Shadow DOM qo'shishni qo'llamaydi". Defissiz taomkarta — brauzer uchun noma'lum oddiy teg, unga Shadow DOM biriktirib bo'lmaydi. template esa oddiy inert qolip bo'lib qoladi. html-validate bu xatoni brauzerdan oldin ushlaydi:

text
  2:2  error  <taomkarta> is not a valid element name  element-name

"taomkarta — yaroqli element nomi emas". Tuzatish: nomda defis — taom-karta.

7.5 Qolipni innerHTML bilan to'ldirish

Foydalanuvchi yozgan matnni HTML sifatida qo'yish — XSS teshigi. Tuzatish: textContent. Batafsil — keyingi darsda.

8. Mashqlar

1-mashq (oson): Nima yuklanadi, nima ishlaydi?

Sahifada ikki blok bor. Sahifa ochilganda qaysi rasm yuklanadi va konsolga nima chiqadi?

html
<template id="a">
  <img src="assets/images/kabob.jpg" alt="">
  <script>console.log("A")</script>
</template>
<div id="b" hidden>
  <img src="assets/images/lagmon.jpg" alt="">
  <script>console.log("B")</script>
</div>
Yechim

Faqat lagmon.jpg yuklanadi va konsolga faqat B chiqadi. Yashirin blok ko'rinmaydi, lekin uning ichidagi rasm yuklanadi va skript ishlaydi. Qolip ichidagi hamma narsa esa inert: kabob.jpg so'ralmaydi, A chiqmaydi — toki JavaScript qolip nusxasini sahifaga qo'ymaguncha.

2-mashq (o'rta): "Bugungi taklif" qolipi

«Bahor» bosh sahifasida "Bugungi takliflar" ro'yxati (ul id="takliflar") bor. Har band: taom nomi (strong), narxi va qisqa izoh. Ro'yxat bandi uchun qolip yozing.

Talablar: qolipning id si taklif-qolip; ichidagi uch joy class bilan belgilangan — nomi, narxi, .

Yechim
html
<ul id="takliflar"></ul>

<template id="taklif-qolip">
  <li>
    <strong class="nomi"></strong> —
    <span class="narxi"></span> so'm.
    <span class="izoh"></span>
  </li>
</template>

li ni template ichiga bemalol yozdik — ul dan tashqarida bo'lsa ham, parser uni saqlaydi. id faqat qolipning o'zida: JavaScript uni shu bilan topadi. Ichkaridagi uch joy — class: har nusxada takrorlanishi mumkin. "so'm" so'zi va tire qolipda — ular har taomda bir xil.

3-mashq (qiyin): Aloqa kartasi

aloqa-karta komponentini shadowrootmode bilan yozing. Ichida uchta slot:

  • manzil nomli — zaxira matni "Manzil ko'rsatilmagan";
  • telefon nomli — zaxira matni "Telefon yo'q";
  • standart slot — zaxira matni "Qo'shimcha ma'lumot yo'q".

Kartani ishlating: manzil — "Toshkent, Chilonzor, 7-mavze", telefon berilmaydi, qo'shimcha — "Mashina qo'yish joyi bor". Brauzerda qaysi uch qator ko'rinishini oldindan yozing.

Yechim
html
<aloqa-karta>
  <template shadowrootmode="open">
    <address>
      <p><slot name="manzil">Manzil ko'rsatilmagan</slot></p>
      <p><slot name="telefon">Telefon yo'q</slot></p>
      <p><slot>Qo'shimcha ma'lumot yo'q</slot></p>
    </address>
  </template>
  <span slot="manzil">Toshkent, Chilonzor, 7-mavze</span>
  <span>Mashina qo'yish joyi bor</span>
</aloqa-karta>

Brauzerda:

text
Toshkent, Chilonzor, 7-mavze
Telefon yo'q
Mashina qo'yish joyi bor

telefon slotiga hech narsa kelmadi — zaxira matn chiqdi. slot atributisiz span standart slotga tushdi.

Qo'shimcha savol: "Mashina qo'yish joyi bor" qatorini olib tashlasak, "Qo'shimcha ma'lumot yo'q" chiqadimi? Yo'q. Teglar orasidagi bo'sh joy va yangi qatorlar standart slotga tushadi va u o'zini to'la deb hisoblaydi. Bu — «Zaxira kontent amalda» bo'limidagi nozik joy. address (Iqtibos, qisqartma, vaqt darsidagi teg) — aloqa ma'lumoti uchun to'g'ri semantik teg. Shadow DOM ichida ham semantika o'z kuchida.

9. Real ishda

  • Ro'yxat va jadvallarni chizish. Freymvorksiz yozilgan loyihalarda (kichik saytlar, brauzer kengaytmalari) serverdan kelgan ma'lumot aynan template + cloneNode bilan sahifaga qo'yiladi.
  • Dizayn tizimlari. GitHub, Adobe, Microsoft kabi kompaniyalar tugma, dialog, sana tanlagich kabi komponentlarni Web Components qilib yozadi. Ular React'da ham, Vue'da ham, oddiy HTML'da ham ishlaydi. Har birining ichida slot lar bor: <ui-tugma>Saqlash</ui-tugma> dagi "Saqlash" — standart slotga tushadi.
  • Lit — Google'ning Web Components uchun kichik kutubxonasi. Unda komponent yozish ancha qisqa (kursda alohida ko'ramiz).
  • Intervyu. "template va yashirin div ning farqi nima?" — yaxshi javob: inert kontent (rasm, skript, forma) va parser qoidalari.

Xulosa

  • template — inert qolip: ko'rinmaydi, rasm yuklanmaydi, skript ishlamaydi, maydon yuborilmaydi, sahifadan qidirilmaydi.
  • Yashirin div qolip o'rnini bosmaydi; template esa tr, li, option kabi elementlarni ham buzmay saqlaydi.
  • JavaScript qolipdan content.cloneNode(true) bilan nusxa oladi, to'ldiradi va sahifaga qo'shadi; qolip ichida id emas, class.
  • slot — Web Component ichidagi bo'sh joy: nomli (name) va standart; bo'sh qolsa — zaxira kontent.
  • Custom element nomida defis majburiy; slot atributi faqat bevosita farzandda ishlaydi.

Keyingi dars: HTML darajasidagi xavfsizlik — XSS, begona skriptlar uchun SRI, CSP, aralash kontent va referrer siyosati.

Manbalar

  • MDN: "<template>: The Content Template element", "<slot>: The Web Component Slot element", "Using templates and slots" — developer.mozilla.org
  • WHATWG HTML Living Standard: "The template element", "The slot element" — html.spec.whatwg.org
  • web.dev: "Declarative Shadow DOM" — web.dev
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
HTML template va slot: ko'rinmas qolip va Web Components uchun joy — IlmHamroh