Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Atribut bilan ishlashning beshta metodi
- 2.1 O'qish va tekshirish
- 2.2 Yozish va o'chirish
- 2.3 toggleAttribute — bor/yo'q almashtirgich
- 3. Xususiyatlar: atributning JavaScript'dagi "egizagi"
- 3.1 Atribut va xususiyat
- 3.2 Nomlari boshqacha bo'lganlar
- 3.3 Xususiyat qiymatni "tozalab" beradi
- 4. value tuzog'i: atribut — boshlang'ich, xususiyat — hozirgi
- 4.1 Foydalanuvchi yozganda nima bo'ladi
- 4.2 Atributni o'zgartirsa-chi?
- 4.3 checked va indeterminate
- 5. Boolean atributlar: borligi — true
- 5.1 disabled="false" tuzog'i
- 5.2 To'g'ri yo'l — xususiyat
- 6. aria-* atributlari — boolean emas!
- 7. data-* atributlari va dataset
- 7.1 O'qish
- 7.2 Hamma qiymat — satr
- 7.3 Yozish va o'chirish
- 7.4 JavaScript yozadi — CSS chizadi
- 7.5 data-* mi, class mi, oddiy atributmi?
- 8. Ko'p uchraydigan xatolar
- 8.1 Hozirgi qiymatni getAttribute("value") bilan o'qish
- 8.2 setAttribute("disabled", false)
- 8.3 dataset dagi qiymatni son deb hisoblash
- 8.4 Chiziqchali nom bilan dataset ga murojaat
- 8.5 Mavjud bo'lmagan xususiyatga yozish
- 9. Mashqlar
- 1-mashq (oson): Havolani tekshiring
- 2-mashq (o'rta): Porsiya tugadi
- 3-mashq (qiyin): Atributlar hisoboti
- 4-mashq: Portfolio qadami — joriy sahifa havolasi
- 10. Real ishda
- Xulosa
- Manbalar
HTML atributlari JavaScript'da: getAttribute, setAttribute, xususiyatlar va dataset
Qisqacha: Atribut — HTML'da yozilgan narsa (
value="Ali"), xususiyat (property) — JavaScript obyektidagi jonli qiymat (input.value). AtributnigetAttribute,setAttribute,removeAttributevatoggleAttributeboshqaradi; ko'p atributning xususiyat "egizagi" ham bor. Ular har doim bir xil emas: foydalanuvchi maydonga yozsa,valuexususiyati o'zgaradi, atribut esa yo'q. O'z ma'lumotingiz uchundata-*atributlari vaelement.datasetishlatiladi.
Bu darsda
getAttribute,setAttribute,hasAttribute,removeAttributevatoggleAttributebilan atributlarni boshqara olasiz.- Atribut va xususiyat farqini, ular qachon bir-birini aks ettirishini tushuntira olasiz.
valuevacheckeddagi "ikki qiymat" tuzog'ini bilasiz.- Boolean va
aria-*atributlarini to'g'ri qo'yasiz va olib tashlaysiz. data-*atributlarinidatasetorqali o'qib-yozasiz va CSS bilan bog'laysiz.
Oldin bilishingiz kerak: Kontentni o'zgartirish va XSS xavfi, Global atributlar, Atribut selektorlari, Obyekt: kalit-qiymat juftliklari.
1. Nega bu kerak?
O'tgan darsda elementning ichini o'zgartirdik. Lekin sahifadagi ko'p narsa ichida emas, atributlarda turadi. Oldingi qismlarda bir nechta va'da qoldirgan edik:
- Atribut selektorlari darsida xatoli telefon maydoni
aria-invalid="true"bilan qizil bo'lardi. "Bu atributni xato tekshirilgandan keyin JavaScript qo'yadi" degan edik. - Navbar va mobil menyu darsida header pastga surilganda yashirinadi —
data-yashirinatributini JavaScript qo'yadi va olib tashlaydi. - Tugmalar tizimi darsida so'rov ketayotgan tugmaga
aria-busy="true"qo'yiladi. - Global atributlar darsida taom kartasiga
data-taom-raqami,data-achchiq,data-porsiyayozgandik: "JavaScript ularnidatasetorqali o'qiydi".
Bugun shu va'dalarning hammasini bajaramiz. Yo'lda esa boshlovchilarni ko'p chalg'itadigan bitta savolga javob beramiz: input.value va input.getAttribute("value") nega har xil qiymat qaytaradi?
2. Atribut bilan ishlashning beshta metodi
2.1 O'qish va tekshirish
Atribut (attribute) — HTML tegida yozilgan nom="qiymat" juftligi (Teg, element va atribut). JavaScript'da ular uchun maxsus metodlar bor:
<a id="bron" href="https://example.com/bron" class="tugma">
Stol band qilish</a>
<script>
const bron = document.querySelector("#bron");
console.log(bron.getAttribute("href"));
console.log(bron.getAttribute("title"));
console.log(bron.hasAttribute("class"), bron.hasAttribute("title"));
console.log(bron.getAttributeNames());
</script>Konsolda:
https://example.com/bron
null
true false
(3) ['id', 'href', 'class']getAttribute(nom)— qiymatni satr sifatida qaytaradi. Atribut yo'q bo'lsa —null(xuddi topilmagan element kabi,undefinedvanull).hasAttribute(nom)— bormi, yo'qmi:trueyokifalse.getAttributeNames()— elementdagi barcha atribut nomlari massivi, HTML'dagi tartibda.
2.2 Yozish va o'chirish
<button id="yubor" type="submit">Yuborish</button>
<script>
const yubor = document.querySelector("#yubor");
yubor.setAttribute("aria-busy", "true");
yubor.setAttribute("title", "Yuborilmoqda");
console.log(yubor);
yubor.removeAttribute("aria-busy");
yubor.removeAttribute("title");
yubor.removeAttribute("yoq-atribut");
console.log(yubor);
</script>Konsolda:
<button id="yubor" type="submit" aria-busy="true" title="Yuborilmoqda">Yuborish</button>
<button id="yubor" type="submit">Yuborish</button>setAttribute(nom, qiymat) atribut bo'lmasa — qo'shadi, bo'lsa — qiymatini almashtiradi. removeAttribute(nom) olib tashlaydi; atribut yo'q bo'lsa ham xato bermaydi. Bu — Tugmalar tizimi darsidagi aria-busy ning JavaScript tomoni: so'rov boshlanganda qo'yiladi, javob kelganda olib tashlanadi. CSS tayyor — atribut paydo bo'lishi bilan tugma o'zgaradi.
Ikki muhim qoida:
setAttributeqiymatni doim satrga aylantiradi.setAttribute("data-soni", 3)— atributda"3"satri turadi.- HTML atribut nomlari katta-kichik harfni farqlamaydi:
setAttribute("ID", "x")— oddiyidga yozadi.
2.3 toggleAttribute — bor/yo'q almashtirgich
Ba'zi atributlarning qiymati muhim emas — faqat borligi muhim. Ular uchun toggleAttribute(nom) bor: atribut bo'lsa olib tashlaydi, bo'lmasa qo'shadi va natijani true/false bilan qaytaradi. Navbar darsidagi yashirinadigan header aynan shu bilan ishlaydi:
<style>
header { background: #2f6b3a; color: #fffaf0; padding: 8px; }
header[data-yashirin] { opacity: 0.2; }
</style>
<header>«Bahor» choyxonasi</header>
<script>
const header = document.querySelector("header");
console.log(header.toggleAttribute("data-yashirin"));
console.log(header);
console.log(header.toggleAttribute("data-yashirin", true));
console.log(header.toggleAttribute("data-yashirin", false));
</script>Konsolda:
true
<header data-yashirin="">«Bahor» choyxonasi</header>
true
falseBirinchi chaqiruv atributni qo'shdi (true — "endi bor"). Ikkinchi argument esa majburlaydi: true — "bo'lsin" (bor edi, qoldi), false — "bo'lmasin". Natijada atribut olib tashlandi va header yana to'liq ko'rinadi. "Tahrirlab ko'rish" bilan oxirgi qatorni o'chirib ko'ring — header xira bo'lib qoladi. Haqiqiy navbar'da opacity emas, translate bor va qaysi tomonga surilayotganini scroll hodisasi aytadi — bu qism keyinroq.
Tekshirib ko'ring:
el.getAttribute("hidden")— element<p hidden>bo'lsa, nima qaytaradi?<p>bo'lsa-chi?
Javob
<p hidden> da — bo'sh satr "": atribut bor, qiymati yozilmagan. <p> da — null: atribut umuman yo'q. Shuning uchun borlikni getAttribute bilan emas, hasAttribute bilan tekshiring: if (el.getAttribute("hidden")) bo'sh satrni false deb biladi va noto'g'ri javob beradi (truthy/falsy).
3. Xususiyatlar: atributning JavaScript'dagi "egizagi"
3.1 Atribut va xususiyat
DOM daraxti darsidan bilasiz: har element — JavaScript obyekti. Obyektning esa xususiyatlari (properties) bor: element.id, element.title. Brauzer HTML'ni o'qiyotganda ko'p standart atributlar uchun shunday xususiyat yasaydi va ularni bog'lab qo'yadi. Biri o'zgarsa — ikkinchisi ham. Buni aks ettirish (reflection) deyishadi.
Hayotdan o'xshatish: choyxonaning menyu doskasi va oshxona. Doskada bo'r bilan yozilgan narx — atribut: hamma ko'radigan, HTML'dagi yozuv. Oshxonadagi kassa dasturidagi narx — xususiyat: dastur aynan shu bilan ishlaydi. Yaxshi choyxonada ikkalasi bir xil. Lekin ba'zan ular ajralib qoladi — buni «value tuzog'i» bo'limida ko'ramiz.
<a id="havola" href="https://example.com/menyu">Menyu</a>
<script>
const havola = document.querySelector("#havola");
console.log(havola.id, havola.getAttribute("id"));
havola.id = "asosiy-menyu";
console.log(havola.getAttribute("id"));
havola.setAttribute("title", "Bugungi taomlar");
console.log(havola.title);
console.log(havola);
</script>Konsolda:
havola havola
asosiy-menyu
Bugungi taomlar
<a id="asosiy-menyu" href="https://example.com/menyu" title="Bugungi taomlar">Menyu</a>Xususiyatga yozdik — atribut o'zgardi. Atributga yozdik — xususiyat o'zgardi. Oddiy holatda ular aynan egizak.
3.2 Nomlari boshqacha bo'lganlar
Ikki atributning xususiyat nomi boshqacha, chunki class va for — JavaScript'ning kalit so'zlari:
| Atribut (HTML) | Xususiyat (JS) | Nega |
|---|---|---|
class |
className (yoki classList) |
class — kalit so'z |
for (label da) |
htmlFor |
for — sikl kalit so'zi |
aria-current |
ariaCurrent |
chiziqcha → camelCase |
data-taom-raqami |
dataset.taomRaqami |
«dataset» bo'limida |
<label id="yorliq" for="ism" class="majburiy">Ism</label>
<input id="ism">
<script>
const yorliq = document.querySelector("#yorliq");
console.log(yorliq.className, yorliq.htmlFor);
console.log(yorliq.class, yorliq.for);
</script>Konsolda:
majburiy ism
undefined undefinedyorliq.class — undefined: bunday xususiyat yo'q. Xato ham chiqmaydi — shuning uchun bu xato uzoq yashirinadi. class bilan ishlashning qulay usuli — classList — keyingi darsda (classList va stillar).
3.3 Xususiyat qiymatni "tozalab" beradi
Ba'zi xususiyatlar atributni shunchaki ko'chirmaydi — uni tayyor ko'rinishga keltiradi. Eng yaqqol misol — href:
<a id="h" href="HTTPS://Example.COM/menyu">Menyu</a>
<a id="b" href="https://example.com">Bosh sahifa</a>
<script>
const h = document.querySelector("#h");
console.log(h.getAttribute("href"));
console.log(h.href);
console.log(h.hostname, h.pathname);
const b = document.querySelector("#b");
console.log(b.getAttribute("href"), b.href);
</script>Konsolda:
HTTPS://Example.COM/menyu
https://example.com/menyu
example.com /menyu
https://example.com https://example.com/Atribut — siz yozgan matn, harfma-harf. Xususiyat — brauzer tushungan to'liq manzil: protokol va domen kichik harfga o'tdi, oxiriga / qo'shildi. Havolada hostname (domen) va pathname (yo'l) kabi qismlar ham bor — ular faqat xususiyat sifatida mavjud.
Nisbiy yo'lda farq yanada katta. Portfolio'ngizning aloqa/ sahifasida href="../loyihalar/" turgan havolani DevTools konsolida tekshirib ko'ring:
const h = document.querySelector('a[href="../loyihalar/"]');
h.getAttribute("href"); // "../loyihalar/" — yozilganidek
h.href; // "http://127.0.0.1:5500/loyihalar/" — to'liq manzil
h.pathname; // "/loyihalar/"Jonli oyna izolyatsiyalangan va o'z manzili yo'q, shuning uchun nisbiy yo'lni u to'liq manzilga aylantira olmaydi — bu misol faqat haqiqiy sahifada ishlaydi. Live Server bo'lmasa, manzil boshqacha bo'ladi.
Amaliy qoida: "HTML'da nima yozilgan?" — getAttribute. "Brauzer aslida qayerga boradi?" — xususiyat.
Tekshirib ko'ring:
<a href="#menyu">uchungetAttribute("href")vahrefxususiyati bir xil chiqadimi?
Javob
Yo'q. getAttribute("href") — "#menyu", yozilganidek. href xususiyati esa to'liq manzil: sahifaning o'z manzili + #menyu, masalan https://example.com/menyu/#menyu. Brauzer har doim to'liq manzilni beradi.
4. value tuzog'i: atribut — boshlang'ich, xususiyat — hozirgi
4.1 Foydalanuvchi yozganda nima bo'ladi
Endi «ajralib qolish» holati. Quyidagi oynada maydonda "Ali" turibdi. Uni o'chirib, o'z ismingizni yozing va Tekshirish tugmasini bosing. Tugma bosilganda kod ishlashi uchun addEventListener("click", ...) — O'tgan darsdagi qolip, to'liq — addEventListener asoslari darsida:
<label for="ism">Ism</label>
<input id="ism" value="Ali">
<button type="button" id="tekshir">Tekshirish</button>
<script>
const ism = document.querySelector("#ism");
console.log(ism.value, ism.getAttribute("value"));
document.querySelector("#tekshir")
.addEventListener("click", () => {
console.log("xususiyat:", ism.value);
console.log("atribut:", ism.getAttribute("value"));
});
</script>Konsolda:
Ali AliSahifa ochilganda ikkalasi "Ali". Endi "Vali" deb yozib, tugmani bosing — konsolda xususiyat: Vali va atribut: Ali chiqadi. Maydonda yozilgan narsa — xususiyatda. Atribut esa HTML'da yozilgan boshlang'ich qiymat bo'lib qoldi.
Bu tasodif emas, qoida. value atributi — boshlang'ich qiymat (sukut bo'yicha). value xususiyati — hozirgi qiymat. Foydalanuvchi yozganda faqat xususiyat o'zgaradi. JavaScript'da ism.value = "..." yozsangiz ham — faqat xususiyat.
Atributni o'qishning xususiyat shakli ham bor — defaultValue. Diagrammada ikki qiymatning yo'li — chapdan o'ngga:
flowchart LR
H["HTML: value=Ali"] --> A["value atributi = defaultValue"]
A -->|"sahifa ochilganda bir marta"| X["value xususiyati"]
F["Foydalanuvchi yozdi"] --> X
J["JS: ism.value = ..."] --> X
S["JS: setAttribute"] --> A
X -.->|"qaytib yozilmaydi"| AO'qlarga qarang: atributdan xususiyatga yo'l bor, teskarisiga — yo'q.
4.2 Atributni o'zgartirsa-chi?
Teskari yo'lni o'zingiz sinab ko'ring. Tugma atributga "Jasur" yozadi va ikkala qiymatni konsolga chiqaradi:
<label for="ism">Ism</label>
<input id="ism" value="Ali">
<button type="button" id="yoz">Atributga Jasur</button>
<script>
const ism = document.querySelector("#ism");
document.querySelector("#yoz")
.addEventListener("click", () => {
ism.setAttribute("value", "Jasur");
console.log("maydonda:", ism.value);
console.log("atribut:", ism.getAttribute("value"));
});
</script>Ikki bosqichda bosing:
- Maydonga tegmasdan tugmani bosing. Maydonda "Jasur" paydo bo'ladi, konsolda
maydonda: Jasurvaatribut: Jasur. Maydon hali "tegilmagan" — brauzer hozirgi qiymatni atributdan olib turibdi. - Endi maydonni tozalab, "Vali" deb yozing va yana bosing. Konsolda
maydonda: Valivaatribut: Jasur. Maydon endi "tegilgan" — brauzer hozirgi qiymatni atributdan olmay qo'ydi.
Qoida shu: foydalanuvchi yozgandan (yoki JavaScript ism.value = ... qilgandan) keyin atribut maydonni boshqarmaydi.
Atribut qachon kerak bo'ladi? Forma tozalanganda. <button type="reset"> (Tugmalar va yuborish) har maydonni atributidagi boshlang'ich qiymatga qaytaradi. Shuning uchun value atributini "tozalashda qaytadigan qiymat" deb tushuning.
Qoida: maydondagi hozirgi matnni o'qish va yozish — doim input.value. getAttribute("value") — faqat boshlang'ich qiymat kerak bo'lsa. Forma qiymatlari bilan ishlashni Forma qiymatlarini o'qish darsida to'liq ko'ramiz.
4.3 checked va indeterminate
Belgilash katagida (checkbox) xuddi shunday juftlik bor: checked atributi — boshlang'ich holat (defaultChecked), checked xususiyati — hozirgi holat.
Bitta holat esa faqat xususiyatda yashaydi — indeterminate (qisman belgilangan). Forma komponentlari darsida "Hamma taomlarni tanlash" katagini qisman holatda bezagan edik. O'shanda "holatni HTML atributi bilan emas, JavaScript xususiyati bilan qo'yamiz" degandik:
<label>
<input type="checkbox" id="hammasi">
Hamma taomlarni tanlash
</label>
<script>
const hammasi = document.querySelector("#hammasi");
hammasi.indeterminate = true;
console.log(hammasi.indeterminate);
console.log(hammasi.hasAttribute("indeterminate"));
console.log(hammasi.matches(":indeterminate"));
</script>Konsolda:
true
false
trueNatijada katak ichida chiziqcha. Atribut yo'q (false), lekin CSS'ning :indeterminate pseudo-klassi holatni ko'radi (matches shuni tasdiqladi). HTML'da indeterminate atributini yozib bo'lmaydi — bunday atribut standartda yo'q.
Tekshirib ko'ring: Foydalanuvchi telefon maydoniga
+998 90 000 00 00yozdi. Dasturchi unigetAttribute("value")bilan o'qib, bo'sh satr oldi. Nega?
Javob
HTML'da value atributi yozilmagan bo'lsa, getAttribute("value") — null; value="" bo'lsa — bo'sh satr. Foydalanuvchi yozgani esa atributga tushmaydi — faqat value xususiyatiga. To'g'ri o'qish: telefon.value.
5. Boolean atributlar: borligi — true
5.1 disabled="false" tuzog'i
disabled, hidden, checked, required, readonly — boolean (mantiqiy) atributlar (Maydon holatlari). Ular uchun qiymat ahamiyatsiz: atribut bor bo'lsa — yoqilgan, yo'q bo'lsa — o'chiq. Hatto disabled="false" ham tugmani o'chiradi:
<button id="bron" type="button" disabled="false">Bron</button>
<script>
const bron = document.querySelector("#bron");
console.log(bron.disabled);
bron.setAttribute("disabled", false);
console.log(bron.disabled, bron.getAttribute("disabled"));
</script>Konsolda:
true
true falseTugma kulrang — bosib bo'lmaydi. "false" — bu bo'sh bo'lmagan satr, brauzer uni "atribut bor" deb tushunadi. setAttribute("disabled", false) ham yordam bermadi: false satrga ("false") aylandi.
5.2 To'g'ri yo'l — xususiyat
Boolean atributlarning xususiyati haqiqiy true/false bilan ishlaydi — eng qulay yo'l shu:
<button id="bron" type="button" disabled>Stol band qilish</button>
<script>
const bron = document.querySelector("#bron");
bron.disabled = false;
console.log(bron.hasAttribute("disabled"), bron);
bron.hidden = true;
console.log(bron);
bron.hidden = false;
</script>Konsolda:
false <button id="bron" type="button">Stol band qilish</button>
<button id="bron" type="button" hidden="">Stol band qilish</button>bron.disabled = false — atribut butunlay olib tashlandi. bron.hidden = true — hidden="" qo'shildi. Xususiyat atributni o'zi boshqaradi.
| Maqsad | ||
|---|---|---|
| Yoqish | el.disabled = true yoki setAttribute("disabled", "") |
— |
| O'chirish | el.disabled = false yoki removeAttribute("disabled") |
setAttribute("disabled", false) |
| Almashtirish | el.toggleAttribute("disabled") |
— |
6. aria-* atributlari — boolean emas!
Mana nozik joy. aria-invalid, aria-expanded, aria-current — ular boolean atribut emas. Ularda qiymat muhim: aria-invalid="false" — "xato yo'q" degani, aria-invalid="true" — "xato bor" (ARIA asoslari). Shuning uchun ular setAttribute bilan aniq satr qiymat oladi.
Atribut selektorlari darsidagi telefon maydonini endi JavaScript bilan ishlatamiz. Bo'sh joylarsiz 13 belgidan (+998 va 9 ta raqam) qisqa bo'lsa — xato. Maydonga raqam yozib, Tekshirish ni bosing:
<style>
[aria-invalid="true"] {
border: 2px solid #b4461a;
outline-color: #b4461a;
}
#telefon-xato { color: #b4461a; }
</style>
<label for="telefon">Telefon raqamingiz</label>
<input id="telefon" type="tel" value="+998 90 12"
aria-describedby="telefon-xato">
<button type="button" id="tekshir">Tekshirish</button>
<p id="telefon-xato"></p>
<script>
const telefon = document.querySelector("#telefon");
const xato = document.querySelector("#telefon-xato");
function telefonniTekshir() {
const raqam = telefon.value.replaceAll(" ", "");
const togri = raqam.length >= 13;
telefon.setAttribute("aria-invalid", String(!togri));
xato.textContent = togri ? "" : "Xato: raqamni to'liq kiriting.";
console.log(telefon.getAttribute("aria-invalid"));
}
telefonniTekshir();
document.querySelector("#tekshir")
.addEventListener("click", telefonniTekshir);
</script>Konsolda:
trueSahifa ochilganda raqam to'liq emas — maydon qizil ramkada, ostida xato matni. Maydonga to'liq raqam yozing (masalan +998 90 000 00 00) va tugmani bosing — konsolda false chiqadi, ramka va xato yo'qoladi.
Kodda uch narsa bor:
String(!togri)—true/falseni aniq"true"/"false"satriga aylantiradi (Turlarni aniq o'zgartirish). Natija bir xil bo'lardi, lekin kod nima qilayotgani ko'rinib turadi.- CSS
[aria-invalid="true"]— qiymat bilan tanlaydi. Agar faqat[aria-invalid]yozilganda,"false"qiymatli maydon ham qizil bo'lardi — atribut bor-da. - Xato matni
textContentbilan,aria-describedbyorqali maydonga bog'langan: Malika NVDA bilan maydonga kelganda "invalid entry" va xato matnini eshitadi.
Haqiqiy forma tekshiruvini (har harf yozilganda, yuborishda) input va change va Constraint Validation API darslarida yozamiz. Bugun — faqat atribut qismi.
aria-* atributlarining ham xususiyat egizaklari bor: el.ariaCurrent, el.ariaInvalid, el.ariaExpanded. Ular 2023-yildan beri hamma asosiy brauzerda ishlaydi (Baseline). Lekin ular ham satr qaytaradi: el.ariaInvalid — "true", true emas. Ko'p jamoalar aniqlik uchun setAttribute ni afzal ko'radi — kurs ham shunday qiladi.
Tekshirib ko'ring:
menyuTugma.setAttribute("aria-expanded", false)— xato bormi?
Javob
Bu holatda xato yo'q. aria-expanded boolean atribut emas, unga "false" satri kerak. setAttribute false ni "false" satriga aylantiradi — aynan kerakli qiymat. disabled bilan bunday yozish esa xato edi. Farq — atribut turida: boolean atributda borlik muhim, aria-* da qiymat.
7. data-* atributlari va dataset
7.1 O'qish
Global atributlar darsida taom kartasiga uchta data-* atribut yozgandik — ekranda ko'rinmaydigan, faqat dastur uchun ma'lumot. Ularning hammasi element.dataset obyektida jamlanadi:
<article class="taom-karta" data-taom-raqami="17"
data-achchiq="2" data-porsiya="12">
<h3>Lag'mon</h3>
</article>
<script>
const karta = document.querySelector(".taom-karta");
console.log(karta.dataset);
console.log(karta.dataset.taomRaqami);
console.log(karta.dataset.yoq);
</script>Konsolda:
DOMStringMap {taomRaqami: '17', achchiq: '2', porsiya: '12'}
17
undefinedNomga qarang: HTML'da data-taom-raqami, JavaScript'da taomRaqami. Qoida:
data-qismi tashlanadi;- har chiziqchadan keyingi harf katta bo'ladi, chiziqcha yo'qoladi (camelCase).
Chiziqcha JavaScript'da ayirish belgisi — karta.dataset.taom-raqami "taom minus raqami" deb o'qilardi. Shuning uchun nom o'zgaradi. Yo'q atribut — undefined (getAttribute dagi null emas).
7.2 Hamma qiymat — satr
dataset dagi hamma narsa satr. Hisoblashdan oldin songa aylantiring:
<article class="taom-karta" data-porsiya="12">
<h3>Lag'mon</h3>
</article>
<script>
const karta = document.querySelector(".taom-karta");
console.log(karta.dataset.porsiya + 1);
console.log(Number(karta.dataset.porsiya) + 1);
</script>Konsolda:
121
13"12" + 1 — satrlar birlashdi: "121" (Yashirin coercion). Number() bilan aylantirgandan keyingina haqiqiy qo'shish bo'ldi (Matn ↔ son).
7.3 Yozish va o'chirish
dataset ga yozish — atributni yozish, delete — o'chirish:
<article class="taom-karta" data-taom-raqami="17"
data-achchiq="2" data-porsiya="12">
<h3>Lag'mon</h3>
</article>
<script>
const karta = document.querySelector(".taom-karta");
karta.dataset.porsiya = Number(karta.dataset.porsiya) - 1;
karta.dataset.tugashVaqti = "21:00";
delete karta.dataset.achchiq;
console.log(karta.getAttribute("data-porsiya"));
console.log(karta.getAttribute("data-tugash-vaqti"));
console.log("achchiq" in karta.dataset);
</script>Konsolda:
11
21:00
falsetugashVaqti HTML'ga teskari yo'l bilan tushdi: katta harf → chiziqcha + kichik harf, oldiga data-. "achchiq" in karta.dataset — in operatori: "shunday kalit bormi?"
7.4 JavaScript yozadi — CSS chizadi
data-* ning eng kuchli tomoni — CSS ularni atribut selektorlari bilan ko'radi. JavaScript faqat ma'lumotni o'zgartiradi, ko'rinishni CSS hal qiladi. Quyidagi oynada Achchiqroq ni bir necha marta bosing:
<style>
.taom-karta { padding: 8px; border: 3px solid #c9d6cf; }
[data-achchiq="1"] { border-color: #e9b38f; }
[data-achchiq="2"] { border-color: #d9773f; }
[data-achchiq="3"] { border-color: #b4461a; }
</style>
<article class="taom-karta" data-achchiq="0">
<h3>Lag'mon</h3>
<p>Achchiqlik: <span class="daraja">0</span></p>
</article>
<button type="button">Achchiqroq</button>
<script>
const karta = document.querySelector(".taom-karta");
const daraja = karta.querySelector(".daraja");
document.querySelector("button")
.addEventListener("click", () => {
let yangi = Number(karta.dataset.achchiq) + 1;
if (yangi > 3) {
yangi = 0;
}
karta.dataset.achchiq = yangi;
daraja.textContent = yangi;
console.log(karta.dataset);
});
</script>Har bosishda ramka rangi to'qlashadi: 1, 2, 3, keyin yana 0 ga qaytadi. Konsolda har safar DOMStringMap {achchiq: '1'} kabi qator chiqadi. JavaScript kodida bitta ham rang yo'q — dizayner Nodira ranglarni o'zgartirmoqchi bo'lsa, faqat CSS'ga tegadi.
7.5 data-* mi, class mi, oddiy atributmi?
| Nima saqlanadi | Nima ishlatiladi | Misol |
|---|---|---|
| Standart ma'noli holat | O'sha standart atribut | disabled, hidden, aria-invalid, aria-current |
| Faqat ko'rinish ("qizil", "katta") | class (keyingi dars) |
taom-karta yangi |
| Dastur uchun ma'lumot, qiymat bilan | data-* |
data-taom-raqami="17" |
Birinchi qatorni unutmang: standart atribut bo'lsa, data-* o'ylab topilmaydi. data-xato="ha" emas — aria-invalid="true": u ekran o'quvchiga ham ishlaydi.
data-* ning yana bir keng tarqalgan ishlatilishi — avtomatik testlar. CSS Modules darsida aytilgandek, testlar elementni o'zgaruvchan class bo'yicha emas, data-testid="savat-tugma" kabi barqaror atribut bo'yicha topadi. Testlarni kursda alohida o'rganamiz.
Tekshirib ko'ring:
<div data-Narx="5000">—datasetda kalit qanday nomlanadi?
Javob
narx. HTML atribut nomlari kichik harfga aylantiriladi, shuning uchun data-Narx aslida data-narx. Katta harf kerak bo'lsa (dataset.taomNarxi), HTML'da chiziqcha yoziladi: data-taom-narxi. Shuning uchun data-* nomlarini doim kichik harf va chiziqcha bilan yozing (Global atributlar darsidagi qoida).
8. Ko'p uchraydigan xatolar
8.1 Hozirgi qiymatni getAttribute("value") bilan o'qish
Foydalanuvchi yozgani u yerda yo'q. Tuzatish: input.value.
8.2 setAttribute("disabled", false)
Tugma baribir o'chiq qoladi («Boolean atributlar» bo'limi). Tuzatish: el.disabled = false yoki removeAttribute("disabled").
8.3 dataset dagi qiymatni son deb hisoblash
dataset.porsiya + 1 → "121". Tuzatish: Number(dataset.porsiya) + 1.
8.4 Chiziqchali nom bilan dataset ga murojaat
<article data-taom-raqami="17"><h3>Lag'mon</h3></article>
<script>
const karta = document.querySelector("article");
console.log(karta.dataset["taom-raqami"]);
console.log(karta.dataset.taomRaqami);
</script>Konsolda:
undefined
17Kvadrat qavsda ham camelCase nomi kerak: dataset["taomRaqami"]. Chiziqchali nom — faqat getAttribute("data-taom-raqami") da.
8.5 Mavjud bo'lmagan xususiyatga yozish
el.class = "yangi" — xato chiqmaydi, lekin atribut o'zgarmaydi: siz obyektga yangi, hech narsaga bog'lanmagan kalit qo'shdingiz. O'zingiz o'ylab topgan nomlar ham shunday: karta.achchiq = 3 HTML'ga tushmaydi. Tuzatish: className/classList, dataset.achchiq yoki setAttribute.
9. Mashqlar
1-mashq (oson): Havolani tekshiring
Har havola uchun konsolga chiqaring: matni va target atributi bormi. Kutilgan natija:
Menyu false
Instagram true<a href="https://example.com/menyu">Menyu</a>
<a href="https://example.com/ig" target="_blank">Instagram</a>
<script>
// shu yerga yozing
</script>Yechim
<a href="https://example.com/menyu">Menyu</a>
<a href="https://example.com/ig" target="_blank">Instagram</a>
<script>
for (const havola of document.querySelectorAll("a")) {
console.log(havola.textContent, havola.hasAttribute("target"));
}
</script>Konsolda:
Menyu false
Instagram truetarget="_blank" li havola yangi tabda ochiladi. Bunday havolalarni topish real auditda foydali: ularga ko'pincha "yangi tabda ochiladi" degan yashirin izoh kerak (Maxsus havolalar va rel).
2-mashq (o'rta): Porsiya tugadi
Har karta uchun data-porsiya ni o'qing. Porsiya 0 bo'lsa — kartaga data-tugadi atributini qo'ying (qiymatsiz) va konsolga Tugadi: <taom nomi> chiqaring. Oxirida tugagan taomlar sonini chiqaring. CSS tayyor: data-tugadi li karta xiralashadi.
Ishora: Number() bilan songa aylantiring; atributni qiymatsiz qo'yish — toggleAttribute(nom, true); taom nomi — kartadagi h3.
<style>
[data-tugadi] { opacity: 0.4; }
</style>
<article class="taom-karta" data-porsiya="12">
<h3>Osh</h3>
</article>
<article class="taom-karta" data-porsiya="0">
<h3>Manti</h3>
</article>
<article class="taom-karta" data-porsiya="0">
<h3>Lag'mon</h3>
</article>
<script>
// shu yerga yozing
</script>Yechim
<style>
[data-tugadi] { opacity: 0.4; }
</style>
<article class="taom-karta" data-porsiya="12">
<h3>Osh</h3>
</article>
<article class="taom-karta" data-porsiya="0">
<h3>Manti</h3>
</article>
<article class="taom-karta" data-porsiya="0">
<h3>Lag'mon</h3>
</article>
<script>
let tugagan = 0;
for (const karta of document.querySelectorAll(".taom-karta")) {
const porsiya = Number(karta.dataset.porsiya);
if (porsiya === 0) {
karta.toggleAttribute("data-tugadi", true);
console.log(`Tugadi: ${karta.querySelector("h3").textContent}`);
tugagan++;
}
}
console.log(`Jami tugagan: ${tugagan}`);
</script>Konsolda:
Tugadi: Manti
Tugadi: Lag'mon
Jami tugagan: 2karta.dataset.tugadi = "" ham xuddi shu atributni qo'yadi. Number() siz "0" === 0 hech qachon true bo'lmasdi — satr va son. «Bahor»da bu holat uchun tugadi class'i ham bor — class bilan qilishni keyingi darsda ko'ramiz.
3-mashq (qiyin): Atributlar hisoboti
Har maydon uchun bitta qator chiqaring: id, majburiymi (required — xususiyat bilan) va boshlang'ich qiymati (value atributi; bo'lmasa —). Keyin JavaScript bilan ism maydoniga "Aziz" yozing va yana bir qator chiqaring: hozirgi qiymat va boshlang'ich qiymat. Kutilgan natija:
ism majburiy: true boshlang'ich: —
telefon majburiy: false boshlang'ich: +998
Hozir: Aziz | boshlang'ich: —Ishora: getAttribute yo'q atributda null beradi — ?? bilan "—" ga almashtiring (??).
<label for="ism">Ism</label>
<input id="ism" required>
<label for="telefon">Telefon</label>
<input id="telefon" type="tel" value="+998">
<script>
// shu yerga yozing
</script>Yechim
<label for="ism">Ism</label>
<input id="ism" required>
<label for="telefon">Telefon</label>
<input id="telefon" type="tel" value="+998">
<script>
for (const maydon of document.querySelectorAll("input")) {
const boshlangich = maydon.getAttribute("value") ?? "—";
console.log(
`${maydon.id} majburiy: ${maydon.required}`,
`boshlang'ich: ${boshlangich}`,
);
}
const ism = document.querySelector("#ism");
ism.value = "Aziz";
const asli = ism.getAttribute("value") ?? "—";
console.log(`Hozir: ${ism.value} | boshlang'ich: ${asli}`);
</script>Konsolda:
ism majburiy: true boshlang'ich: —
telefon majburiy: false boshlang'ich: +998
Hozir: Aziz | boshlang'ich: —maydon.required — boolean xususiyat, haqiqiy true/false. getAttribute("required") esa "" yoki null qaytarardi. JavaScript'dan value ga yozish ham atributni o'zgartirmadi — «value tuzog'i» bo'limidagi qoida.
4-mashq: Portfolio qadami — joriy sahifa havolasi
Portfolio menyusidagi aria-current="page" ni 04-qismda har sahifaga qo'lda yozgansiz. Yangi sahifa qo'shilganda uni unutish oson. O'tgan darsdan oldingi menyuniTop funksiyasi joriy havolani faqat o'qigan edi. Endi joriyHavolaniBelgila funksiyasi uni tekshirsin va tuzatsin:
- Menyuni toping;
404.htmlda u yo'q — jim tugasin. - Har havola uchun solishtiring: havolaning
pathnamexususiyati sahifaning manzililocation.pathnamega tengmi (Brauzer muhiti darsidagi BOM). Bosh sahifa ba'zan/index.html, ba'zan/bo'lib ochiladi — ikkala yo'ldan oxiridagiindex.htmlni olib tashlab solishtiring (endsWith,slice— Matn ichida qidirish, Kesish). - Mos havolada
aria-currentbo'lmasa —console.warnbilan ogohlantirib, qo'ying. Mos bo'lmagan havolada bo'lsa — ogohlantirib, olib tashlang. - Qo'shimcha:
<html>gadata-jsatributini qo'ying (datasetbilan). Bu "JavaScript ishladi" degan belgi — keyingi darslarda faqat JavaScript bilan ishlaydigan tugmalarni (tema, mobil menyu) CSS shunga qarab ko'rsatadi.
Commit: JS: joriy sahifa havolasini avtomatik belgila.
Yechim
asosiy.js ga (menyuniTop dan keyin):
function yolniTozala(yol) {
if (yol.endsWith("index.html")) {
return yol.slice(0, -"index.html".length);
}
return yol;
}
function joriyHavolaniBelgila() {
const menyu = document.querySelector(
'nav[aria-label="Asosiy menyu"]',
);
if (menyu === null) {
return;
}
const joriyYol = yolniTozala(location.pathname);
for (const havola of menyu.querySelectorAll("a")) {
const mos = yolniTozala(havola.pathname) === joriyYol;
const belgili = havola.hasAttribute("aria-current");
if (mos && !belgili) {
console.warn(`aria-current yo'q: ${havola.textContent}`);
havola.setAttribute("aria-current", "page");
} else if (!mos && belgili) {
console.warn(`Ortiqcha aria-current: ${havola.textContent}`);
havola.removeAttribute("aria-current");
}
}
}
document.documentElement.dataset.js = "bor";
joriyHavolaniBelgila();Nega getAttribute("href") emas, pathname xususiyati? HTML'da bosh sahifaga ../, ./ yoki ../../ yozilgan — sahifaga qarab har xil. Xususiyat esa brauzer hisoblagan to'liq yo'lni beradi, uni sahifa manzili bilan to'g'ridan-to'g'ri solishtirsa bo'ladi.
Sinov: Live Server bilan aloqa/ sahifasini oching va DevTools → Elements'da aria-current ni qo'lda boshqa havolaga ko'chiring. Sahifani yangilasangiz — HTML'dagi asl holat qaytadi, shuning uchun sinovni HTML faylda qiling: bitta sahifada aria-current ni ataylab noto'g'ri havolaga yozing. Konsolda ikki sariq ogohlantirish chiqadi, Elements panelida esa belgi to'g'ri havolada turadi. Keyin HTML'ni tuzatib qo'ying — ogohlantirish yo'qolishi kerak. Elements'da <html ... data-js="bor"> ni ham ko'rasiz.
aria-current ni HTML'dan olib tashlamang: JavaScript ishlamasa ham Malika joriy sahifani eshitishi kerak. JavaScript — faqat tekshiruvchi va zaxira.
10. Real ishda
- Forma tekshiruvi —
aria-invalid,aria-describedby,disabledni JavaScript qo'yadi. Ularni noto'g'ri qo'yish (disabled="false") — real loyihalardagi tez-tez uchraydigan xato. data-*— HTML va JavaScript orasidagi ko'prik. Server sahifani chizganda kartagadata-taom-raqamiyozadi, JavaScript esa "savatga qo'shish" bosilganda shu raqamni serverga yuboradi (fetch).- Testlar elementni
data-testidbo'yicha topadi — dizayn o'zgarsa ham test buzilmaydi. - Freymvorklarda (React — kursda alohida o'rganamiz) ham shu farq bor: React'da
valuevadefaultValuealohida — bugungi "boshlang'ich va hozirgi qiymat" g'oyasining o'zi. - Intervyuda so'raladi: "Atribut va xususiyat (property) farqi nima?" Eng yaxshi javob —
valuemisoli bilan.
Xulosa
- Atribut — HTML'dagi yozuv (
getAttribute/setAttribute/hasAttribute/removeAttribute/toggleAttribute); xususiyat — obyektdagi jonli qiymat. - Ko'p atributlar xususiyat bilan aks etadi, ba'zilari boshqa nomda:
className,htmlFor;hrefxususiyati — to'liq manzil. value/checkedatributi — boshlang'ich qiymat; xususiyat — hozirgi. Foydalanuvchi faqat xususiyatni o'zgartiradi.- Boolean atributda borlik muhim (
disabled="false"ham o'chiradi) — xususiyat bilan boshqaring;aria-*da esa qiymat muhim. data-taom-raqami→dataset.taomRaqami; qiymatlar doim satr; CSS ularni atribut selektori bilan ko'radi.
Keyingi dars: classList va stillarni JS'dan boshqarish — class'larni qo'shish va olib tashlash, inline stil, CSS o'zgaruvchilari va getComputedStyle.
Manbalar
- MDN: "Element: getAttribute() method", "Element: toggleAttribute() method", "HTMLElement: dataset property" — developer.mozilla.org
- MDN: "HTML attribute reference: Boolean attributes", "Attribute reflection" — developer.mozilla.org
- HTML Standard: "Reflecting content attributes in IDL attributes" — html.spec.whatwg.org
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!