Custom Data Attributes — data-* va JavaScript bilan ishlash
Muammodan boshlaylik
Mahsulotlar ro'yxati. "Savatga" tugmasi bosilganda JavaScript qaysi mahsulot ekanini, uning narxini va qolgan miqdorini bilishi kerak:
<div class="product">
<h3>Noutbuk Pro 14</h3>
<p>12 500 000 so'm</p>
<button>Savatga</button>
</div>
Variantlar:
- Narxni matndan "kesib olish" —
"12 500 000 so'm"ni songa aylantirish. Mo'rt: dizayner "so'm" ni "UZS" ga o'zgartirsa — kod buziladi id="product-42"vaclass="price-12500000"kabi hiylalar —idvaclassboshqa maqsadlar uchun- Har bir tugma uchun alohida JavaScript — 100 ta mahsulot, 100 ta funksiya
HTML elementiga o'zingizning ma'lumotingizni biriktirishning standart usuli bor — data-* atributlari.
Sintaksis
<button
class="btn"
data-product-id="42"
data-price="12500000"
data-stock="7"
>
Savatga
</button>
- Nomi
data-bilan boshlanadi, keyin o'zingiz tanlagan nom - Nomda: kichik harflar, raqamlar, chiziqcha (
data-product-id) - Qiymat — har doim matn (string)
- Brauzer ularga hech qanday ma'no bermaydi — faqat saqlaydi
Bu atributlar HTML standartiga to'liq mos (validatsiyadan o'tadi) va boshqa hech qaysi atribut bilan to'qnashmaydi.
JavaScript bilan o'qish — dataset
const btn = document.querySelector('.btn');
btn.dataset.productId // "42"
btn.dataset.price // "12500000"
btn.dataset.stock // "7"
dataset — elementning barcha data-* atributlari obyekti. Nomlar avtomatik aylantiriladi:
| HTML | JavaScript |
|---|---|
data-id |
dataset.id |
data-product-id |
dataset.productId |
data-max-items-count |
dataset.maxItemsCount |
Chiziqchadan keyingi harf katta bo'ladi (camelCase).
Yozish va o'chirish
btn.dataset.stock = '6'; // HTML da: data-stock="6"
btn.dataset.loading = 'true'; // yangi atribut: data-loading="true"
delete btn.dataset.loading; // atributni o'chirish
Turlar — doim matn
const price = Number(btn.dataset.price); // 12500000 — son
const isActive = btn.dataset.active === 'true'; // boolean
const tags = JSON.parse(btn.dataset.tags); // massiv yoki obyekt (data-tags='["css","grid"]')
[!WARNING]
datasetdan olingan qiymat har doim string.btn.dataset.price + 1000→"125000001000"(matnlar birlashadi), son emas. Hisob-kitobdan oldinNumber()bilan aylantiring.
Darsning boshidagi muammo — hal
<div class="products">
<article class="product">
<h3>Noutbuk Pro 14</h3>
<p>12 500 000 so'm</p>
<button class="add-to-cart" data-id="42" data-price="12500000">Savatga</button>
</article>
<article class="product">
<h3>Telefon X</h3>
<p>8 900 000 so'm</p>
<button class="add-to-cart" data-id="43" data-price="8900000">Savatga</button>
</article>
<!-- ... 100 ta mahsulot -->
</div>
document.querySelector('.products').addEventListener('click', (e) => {
const btn = e.target.closest('.add-to-cart');
if (!btn) return;
const id = Number(btn.dataset.id);
const price = Number(btn.dataset.price);
savatgaQoshish(id, price);
});
- Bitta event listener butun ro'yxat uchun ("event delegation")
- Ma'lumot ko'rinadigan matndan emas —
data-*dan; dizayn o'zgarsa ham kod buzilmaydi - Yangi mahsulot qo'shilsa — hech qanday JavaScript o'zgarishi kerak emas
CSS bilan ishlatish
data-* atributlari CSS selektorlarida ham ishlaydi (CSS kursi, 3-dars):
/* Holat bo'yicha stil */
.btn[data-loading="true"] {
opacity: 0.6;
cursor: wait;
}
/* Qiymatni ko'rsatish */
.badge::after {
content: attr(data-count);
}
/* Variantlar */
.alert[data-type="error"] { background: #fee2e2; }
.alert[data-type="success"] { background: #dcfce7; }
<span class="badge" data-count="3"></span> <!-- ko'rinishi: 3 -->
<div class="alert" data-type="error">Xatolik!</div>
Qorong'i rejim — DevDocs dagi kabi:
<html data-theme="dark">
[data-theme="dark"] {
--bg: #0b0f19;
--matn: #f1f5f9;
}
document.documentElement.dataset.theme = 'dark';
Qachon ishlatish va qachon ishlatmaslik
| ✅ Yaxshi | ❌ Yomon |
|---|---|
JavaScript uchun ID va konfiguratsiya: data-id, data-url |
Maxfiy ma'lumot — HTML ni har kim ko'radi (Ctrl+U) |
Holat: data-state="open", data-loading |
Mavjud atribut bor bo'lsa: disabled, hidden, aria-expanded, href |
Test uchun belgilar: data-testid="login-btn" |
Katta hajmdagi ma'lumot — JSON da yoki JavaScript da saqlang |
| Kichik CSS variantlari | Foydalanuvchi ko'rishi kerak bo'lgan matn — u sahifa matnida bo'lsin |
[!INFO] Accessibility ga tegishli holatlar uchun avval ARIA atributlarini qidiring (21-dars): menyu ochiqmi —
aria-expanded="true", joriy sahifa —aria-current="page". Ular ham CSS da ishlaydi ([aria-expanded="true"]), va qo'shimcha ravishda ekran o'quvchilarga ham holatni aytadi.data-*— faqat ARIA mos kelmaydigan, sof ichki ma'lumot uchun.
Nima uchun shunday?
Nima uchun maxsus data- prefiksi — shunchaki price="12500000" yozsa bo'lmaydimi?
Ishlaydi, lekin xavfli. HTML standarti rivojlanib boradi va yangi atributlar qo'shiladi. Bugun siz o'ylab topgan price yoki loading atributi ertaga rasmiy atributga aylanishi mumkin — va brauzer unga o'z ma'nosini beradi (masalan, loading allaqachon rasmlar uchun rasmiy atribut: loading="lazy"). Natijada sizning kodingiz kutilmaganda buziladi. data- prefiksi — HTML standartining va'dasi: "bu nomlar fazosi sizniki, biz unga hech qachon hech narsa qo'shmaymiz". Bu dasturlashdagi nomlar to'qnashuvining oldini olishning klassik usuli — xuddi CSS dagi BEM (CSS kursi, 33-dars) kabi.
Xulosa
Eslab qoling:
data-nom="qiymat"— elementga o'z ma'lumotingizni biriktirish; standartga mos- JavaScript:
el.dataset.nom;data-product-id→dataset.productId - Qiymat doim string —
Number(),=== 'true',JSON.parse() - Yozish:
el.dataset.x = '...'; o'chirish:delete el.dataset.x - CSS:
[data-state="open"],content: attr(data-count) - Event delegation +
data-*— bitta listener ko'p element uchun - Maxfiy ma'lumot yo'q; ARIA mos kelsa — ARIA
Keyingi bo'lim
3-bo'lim: Formalar — foydalanuvchidan ma'lumot olish: input turlari, select, textarea va validatsiya.