Custom Data Attributes — data-* va JavaScript bilan ishlash

~15 daq · HTML · Semantik HTML va Meta

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" va class="price-12500000" kabi hiylalar — id va class boshqa 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] dataset dan olingan qiymat har doim string. btn.dataset.price + 1000 → "125000001000" (matnlar birlashadi), son emas. Hisob-kitobdan oldin Number() 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.