DOM: sahifani JavaScript bilan o'zgartirish
Hozirgacha JavaScript faqat konsolga yozdi. Endi u sahifaning o'zini boshqaradi: matnni almashtiradi, rang beradi, rasmni o'zgartiradi, yangi elementlar qo'shadi. Bularning hammasi DOM orqali amalga oshadi — bu dars JavaScript'ning eng «ko'rinadigan» qismi.
Bu darsda
- DOM nima va nega uni «daraxt» deyishadi
- Elementni topish:
getElementById,querySelector,querySelectorAll - Matnni o'zgartirish:
textContent,innerHTML,value - Uslub va klasslar:
stylevaclassList - Atributlar va yangi element yaratish
- Eng ko'p uchraydigan xato —
nullva uni tuzatish
DOM nima?
Brauzer HTML faylni o'qiganda uni shunchaki matn sifatida ko'rsatmaydi. U har bir tegdan JavaScript obyekti yasaydi va ularni «kim kimning ichida» tartibida daraxtga joylaydi. Shu daraxt DOM (inglizcha Document Object Model — «hujjatning obyekt modeli») deyiladi.
Mana oddiy sahifa:
<!doctype html>
<html>
<head>
<title>Mening sahifam</title>
</head>
<body>
<h1>Salom!</h1>
<p>Birinchi xatboshi</p>
<ul>
<li>Olma</li>
<li>Anor</li>
</ul>
</body>
</html>
Brauzer undan quyidagi daraxtni quradi:
Bu xuddi oila shajarasiga o'xshaydi. body — h1, p va ul ning «otasi» (inglizcha parent), ular esa uning «bolalari» (children). Ikkala li bir-biriga «aka-uka». Daraxtning eng tepasida document turadi — butun sahifa.
Eng muhimi: JavaScript shu daraxtdagi obyektlarni o'zgartirsa, brauzer sahifani darhol qayta chizadi. HTML faylning o'zi o'zgarmaydi — o'zgarish faqat brauzer xotirasidagi daraxtda bo'ladi.
Daraxtga kirish eshigi — document obyekti. U doim tayyor turadi:
<title>Mening sahifam</title>
<h1 id="sarlavha">Salom, DOM!</h1>
<p>Bu sahifa — daraxt.</p>
<script>
console.log(document.title);
console.log(document.querySelector("h1"));
console.log(document.querySelector("h1").textContent);
</script>
Konsolda <h1#sarlavha> — bu element obyekti: JavaScript sahifadagi sarlavhani «qo'liga oldi». Endi u bilan istalgan ishni qilish mumkin.
Elementni topish
Element bilan ishlashdan oldin uni topish kerak. Buning uchun asosan uchta metod ishlatiladi:
| Metod | Nima qaytaradi |
|---|---|
document.getElementById("sarlavha") | id si shu bo'lgan element (# belgisisiz yoziladi) |
document.querySelector("css-selektor") | Selektorga mos birinchi element |
document.querySelectorAll("css-selektor") | Mos keladigan barcha elementlar ro'yxati |
querySelector ga 8-darsdagi CSS selektorlarining istalganini berish mumkin: "h1" (teg), ".meva" (klass), "#sarlavha" (id), "ul li" (ichidagi) va hokazo.
<h1 id="sarlavha">Mevalar</h1>
<ul>
<li class="meva">Olma</li>
<li class="meva qizil">Anor</li>
<li class="meva">Uzum</li>
</ul>
<script>
const sarlavha = document.getElementById("sarlavha");
console.log(sarlavha);
const birinchi = document.querySelector(".meva"); // birinchi .meva
console.log(birinchi.textContent);
const qizil = document.querySelector("li.qizil");
console.log(qizil.textContent);
const hammasi = document.querySelectorAll(".meva"); // barchasi
console.log("Soni:", hammasi.length);
hammasi.forEach(function (li) {
console.log("-", li.textContent);
});
console.log(document.querySelector(".banan")); // topilmadi
</script>
querySelectorAllmassivga o'xshash ro'yxat qaytaradi: undalengthbor, elementlarniforEachbilan aylanib chiqish yoki indeks bilan olish mumkin (hammasi[0]).- Element topilmasa,
querySelectornull(«hech narsa») qaytaradi. Bu muhim — dars oxirida bunga qaytamiz.
Ko'pincha querySelector va querySelectorAll ning o'zi yetarli: ular istalgan CSS selektorni tushunadi. getElementById("x") — querySelector("#x") ning eski, lekin hamon ko'p uchraydigan ko'rinishi.
Matnni o'zgartirish
Elementning ichidagi narsani o'qish va almashtirishning ikki yo'li bor:
textContent— elementning matni. Teglar bo'lsa, ular oddiy belgilar sifatida ko'rinadi.innerHTML— elementning ichidagi HTML. Teglar haqiqiy teg sifatida ishlaydi.
<style> body { font-family: sans-serif; } </style>
<h1>Eski sarlavha</h1>
<p id="birinchi">Bu matn o'zgaradi.</p>
<p id="ikkinchi"></p>
<script>
const h1 = document.querySelector("h1");
h1.textContent = "Yangi sarlavha!";
// textContent: teglar oddiy matn bo'lib ko'rinadi
document.querySelector("#birinchi").textContent = "Bu <b>qalin</b> emas";
// innerHTML: teglar HTML sifatida ishlaydi
document.querySelector("#ikkinchi").innerHTML = "Bu <b>qalin</b> matn";
</script>
Xavfsizlik qoidasi: foydalanuvchi yozgan matnni hech qachon innerHTML ga qo'ymang. Kimdir forma maydoniga matn o'rniga <img src=x onerror="…"> kabi HTML yozsa, innerHTML uni haqiqiy element qilib yaratadi va ichidagi begona JavaScript kod ishga tushib ketadi. Foydalanuvchi matni uchun doim textContent ishlating. innerHTML esa faqat o'zingiz yozgan, ishonchli HTML uchun.
Kiritish maydonining qiymati: value
<input>, <textarea> va <select> ichiga yozilgan narsa textContent da emas, value xususiyatida turadi (formalar darsini eslang):
<style>
body { font-family: sans-serif; }
input { margin: 4px 0; padding: 6px; }
</style>
<input id="ism" value="Aziza">
<input id="shahar" placeholder="Shahar">
<p id="natija"></p>
<script>
const ism = document.querySelector("#ism");
const shahar = document.querySelector("#shahar");
shahar.value = "Buxoro"; // maydonga yozamiz
// maydonlardan o'qiymiz
document.querySelector("#natija").textContent =
ism.value + " " + shahar.value + "da yashaydi.";
</script>
Maydonlardagi matnni o'zgartirib ko'ring — pastdagi xatboshi o'zgarmaydi. Chunki skript faqat bir marta, sahifa ochilganda ishladi. Foydalanuvchi yozgan sari javob berishni keyingi darsda — hodisalar yordamida o'rganamiz.
Uslubni o'zgartirish
style xususiyati
Har bir elementda style obyekti bor. Unga CSS xususiyatlarini yozish mumkin. Faqat bitta farq bor: CSS'dagi chiziqchali nomlar JavaScript'da camelCase («tuya yozuvi») bilan yoziladi — chiziqcha olib tashlanadi, keyingi harf katta bo'ladi:
| CSS'da | JavaScript'da |
|---|---|
color | style.color |
background-color | style.backgroundColor |
font-size | style.fontSize |
border-radius | style.borderRadius |
<h1>Salom!</h1>
<p>Bu sahifani JavaScript bezadi.</p>
<script>
const h1 = document.querySelector("h1");
h1.style.color = "white";
h1.style.backgroundColor = "teal"; // background-color
h1.style.padding = "12px";
h1.style.borderRadius = "8px"; // border-radius
h1.style.fontFamily = "sans-serif"; // font-family
document.querySelector("p").style.fontSize = "20px";
</script>
Qiymatlar doim satr sifatida, CSS'dagidek birligi bilan yoziladi: "20px", faqat 20 emas.
classList — yaxshiroq usul
Ko'p xususiyatni JavaScript'da birma-bir yozish noqulay. Odatda boshqacha qilinadi: ko'rinish CSS'da klass sifatida oldindan tayyorlab qo'yiladi, JavaScript esa faqat shu klassni qo'shadi yoki olib tashlaydi. Buning uchun classList bor:
| Metod | Nima qiladi |
|---|---|
classList.add("x") | Klass qo'shadi |
classList.remove("x") | Klassni olib tashlaydi |
classList.toggle("x") | Bor bo'lsa olib tashlaydi, yo'q bo'lsa qo'shadi |
classList.contains("x") | Klass bormi? — true yoki false |
<style>
body { font-family: sans-serif; }
.karta { padding: 12px; margin: 8px 0;
border: 2px solid #ccc; border-radius: 10px; }
.tanlangan { border-color: teal; background: #e0f5f3; font-weight: bold; }
.yashirin { display: none; }
</style>
<div class="karta" id="k1">1-karta</div>
<div class="karta" id="k2">2-karta</div>
<div class="karta" id="k3">3-karta</div>
<script>
document.querySelector("#k1").classList.add("tanlangan");
document.querySelector("#k3").classList.add("yashirin");
const k2 = document.querySelector("#k2");
k2.classList.toggle("tanlangan"); // yo'q edi — qo'shildi
k2.classList.toggle("tanlangan"); // bor edi — olib tashlandi
console.log(k2.classList.contains("tanlangan"));
</script>
Uchinchi karta yashirin klassi tufayli ko'rinmay qoldi. Ikkinchi toggle qatorini o'chirib ko'ring — 2-karta ham tanlangan bo'ladi.
toggle — chiroq kaliti kabi: bir bosilsa yoqiladi, yana bosilsa o'chadi. Tugma bosilganda menyuni ochib-yopish, tungi rejimni yoqib-o'chirish uchun aynan shu ishlatiladi.
Nega classList yaxshiroq? Ko'rinish CSS'da, mantiq JavaScript'da qoladi — har kim o'z ishini qiladi. Dizaynni o'zgartirish uchun JavaScript'ga tegish shart emas, bitta klass esa bir yo'la o'nlab xususiyatni o'zgartira oladi.
Atributlar
Teglarning atributlarini (src, href, alt, placeholder va boshqalar) ham o'qish va o'zgartirish mumkin:
element.getAttribute("src")— atribut qiymatini o'qiydi;element.setAttribute("src", "yangi.svg")— atributga yangi qiymat beradi.
<style>
body { font-family: sans-serif; }
img { width: 200px; border-radius: 8px; }
</style>
<img id="rasm" src="../assets/rasmlar/olma.svg" alt="Olma">
<p id="izoh"></p>
<script>
const rasm = document.querySelector("#rasm");
console.log("Avval:", rasm.getAttribute("src"));
rasm.setAttribute("src", "../assets/rasmlar/tog.svg");
rasm.setAttribute("alt", "Tog' manzarasi");
console.log("Keyin:", rasm.getAttribute("src"));
const izoh = document.querySelector("#izoh");
izoh.textContent = "Rasm: " + rasm.getAttribute("alt");
</script>
Olma o'rniga tog' rasmi chiqdi. tog.svg ni registon.svg ga almashtirib ko'ring. Ko'p atributlarni xususiyat sifatida to'g'ridan-to'g'ri ham yozish mumkin: rasm.alt = "…", havola.href = "…".
Yangi element yaratish
JavaScript sahifaga butunlay yangi elementlar qo'sha oladi. Bu uch qadamda bajariladi:
document.createElement("li")— yangi element yasash;li.textContent = "…"— uni to'ldirish (klass, atribut ham berish mumkin);royxat.append(li)— sahifadagi biror elementning ichiga joylash (oxiriga). Boshiga qo'yish uchun —prepend.
Elementni o'chirish esa bitta buyruq: element.remove().
Bu g'isht terishga o'xshaydi: avval g'ishtni quyasiz (createElement), keyin unga naqsh solasiz (textContent), so'ng devorga terasiz (append). Devorga terilmaguncha g'ishtni hech kim ko'rmaydi — append qilinmagan element ham sahifada ko'rinmaydi.
<style> body { font-family: sans-serif; } </style>
<h3>Xaridlar ro'yxati</h3>
<ul id="royxat">
<li>Non</li>
<li id="ortiqcha">Shakar</li>
</ul>
<script>
const royxat = document.querySelector("#royxat");
const yangi = document.createElement("li"); // 1) yasash
yangi.textContent = "Sut"; // 2) to'ldirish
royxat.append(yangi); // 3) joylash
const p = document.createElement("p");
p.textContent = "Ro'yxat JavaScript bilan yangilandi.";
p.style.color = "green";
document.body.append(p);
document.querySelector("#ortiqcha").remove(); // o'chirish
</script>
Massivdan sahifa yasash
Endi 15-darsdagi massivlar kuchga kiradi. Odatda ma'lumot massivda saqlanadi, sahifa esa sikl yordamida shu massivdan quriladi:
<style>
body { font-family: sans-serif; }
.mahsulot { display: flex; justify-content: space-between;
padding: 8px 12px; border-bottom: 1px solid #ddd; }
.arzon { color: green; font-weight: bold; }
</style>
<h3>Mahsulotlar</h3>
<div id="joy"></div>
<script>
const mahsulotlar = [
{ nomi: "Non", narx: 4000 },
{ nomi: "Sut", narx: 12000 },
{ nomi: "Pishloq", narx: 38000 },
{ nomi: "Choy", narx: 9000 }
];
const joy = document.querySelector("#joy");
for (const m of mahsulotlar) {
const qator = document.createElement("div");
qator.classList.add("mahsulot");
const nom = document.createElement("span");
nom.textContent = m.nomi;
const narx = document.createElement("span");
narx.textContent = m.narx + " so'm";
if (m.narx < 10000) {
narx.classList.add("arzon");
}
qator.append(nom, narx); // ikkalasini qatorga
joy.append(qator); // qatorni sahifaga
}
</script>
Massivga yangi mahsulot qo'shing, masalan { nomi: "Asal", narx: 60000 } — sahifada yangi qator o'zi paydo bo'ladi. HTML'ga tegmadik! «Ma'lumot massivda, sahifa undan quriladi» degan g'oya 18-darsdagi loyihaning asosi bo'ladi.
Eng ko'p uchraydigan xato: null
Quyidagi kodda xato bor. Natijaga va konsolga qarang:
<script>
const sarlavha = document.querySelector("h1");
sarlavha.textContent = "JavaScript ishladi!";
</script>
<h1>Sarlavha</h1>
Konsolda Cannot set properties of null («null'ning xususiyatini o'zgartirib bo'lmaydi») degan xato chiqdi, sarlavha esa o'zgarmadi. Nima bo'ldi?
- Brauzer HTML'ni yuqoridan pastga o'qiydi va
<script>ga yetishi bilan uni darhol bajaradi. - Shu paytda
<h1>hali o'qilmagan — u DOM'da yo'q.querySelector("h1")hech narsa topolmay,nullqaytaradi. null.textContent = …— «hech narsaning matnini o'zgartir» degani. Bu mumkin emas, shuning uchun xato.
Bu hali qurilmagan uyning eshigini bo'yashga urinishga o'xshaydi. Avval uy qurilishi, keyin bo'yoqchi kelishi kerak.
Yechim — skript ishlaganda elementlar allaqachon tayyor bo'lsin. Ikki usul bor.
1-usul. <script> ni <body> ning eng oxiriga, barcha elementlardan keyin qo'ying:
<h1>Sarlavha</h1>
<script>
const sarlavha = document.querySelector("h1");
sarlavha.textContent = "JavaScript ishladi!";
</script>
2-usul. JavaScript alohida faylda bo'lsa (haqiqiy saytlarda odatda shunday), uni <head> ichida defer atributi bilan ulang. defer («kechiktirish») brauzerga «faylni yuklab ol, lekin HTML to'liq o'qilgandan keyin ishga tushir» deydi:
<!doctype html> <html lang="uz"> <head> <meta charset="utf-8"> <title>Mening sahifam</title> <link rel="stylesheet" href="style.css"> <script src="script.js" defer></script> </head> <body> <h1>Sarlavha</h1> </body> </html>
defer faqat src bilan ulangan tashqi faylda ishlaydi. Bu saytdagi muharrirlarda kod bitta oynada yoziladi, shuning uchun biz <script> ni doim elementlardan keyin qo'yamiz.
Konsolda null yoki undefined haqida xato ko'rsangiz, birinchi navbatda ikki narsani tekshiring: selektor to'g'ri yozilganmi ("#sarlavha" va "sarlavha" — boshqa-boshqa narsa!) va skript elementdan keyin turibdimi.
Mashqlar
1-mashq Sarlavhani o'zgartiring
HTML qismiga tegmasdan, faqat JavaScript yordamida <h1> matnini Salom, DOM! ga, rangini esa teal ga o'zgartiring.
<h1>Eski sarlavha</h1> <p>Bu sahifani JavaScript o'zgartiradi.</p> <script> // 1) h1 ni toping // 2) matnini o'zgartiring // 3) rangini teal qiling </script>
Yechimni ko'rish
<h1>Eski sarlavha</h1>
<p>Bu sahifani JavaScript o'zgartiradi.</p>
<script>
const h1 = document.querySelector("h1");
h1.textContent = "Salom, DOM!";
h1.style.color = "teal";
</script>
2-mashq Faol menyu bandi
CSS'da .faol klassi tayyor. JavaScript yordamida uni faqat ikkinchi <li> ga («Darslar») qo'shing. HTML'ni o'zgartirmang.
<style>
body { font-family: sans-serif; }
li { padding: 6px 10px; border-radius: 6px; }
.faol { background: gold; font-weight: bold; }
</style>
<ul>
<li>Bosh sahifa</li>
<li>Darslar</li>
<li>Aloqa</li>
</ul>
<script>
// Ikkinchi li ga "faol" klassini qo'shing
</script>
Ishora
document.querySelectorAll("li") ro'yxat qaytaradi. Massivdagidek, ikkinchi elementning indeksi — 1.
Yechimni ko'rish
<style>
body { font-family: sans-serif; }
li { padding: 6px 10px; border-radius: 6px; }
.faol { background: gold; font-weight: bold; }
</style>
<ul>
<li>Bosh sahifa</li>
<li>Darslar</li>
<li>Aloqa</li>
</ul>
<script>
const bandlar = document.querySelectorAll("li");
bandlar[1].classList.add("faol");
</script>
Boshqa usul: document.querySelector("li:nth-child(2)") — «ota elementidagi ikkinchi bola» degan CSS selektor.
3-mashq Massivdan ro'yxat
mevalar massividagi har bir meva uchun <li> yarating va uni #royxat ga qo'shing. Kod massivga yangi meva qo'shilganda ham ishlashi kerak — har bir elementni qo'lda yozmang, sikl ishlating.
<style> body { font-family: sans-serif; } </style>
<h3>Mevalar</h3>
<ul id="royxat"></ul>
<script>
const mevalar = ["olma", "anor", "uzum"];
// Har bir meva uchun li yasab, #royxat ga qo'shing
</script>
Ishora
Avval const royxat = document.querySelector("#royxat");. Keyin for (const meva of mevalar) { … } ichida uch qadam: createElement, textContent, append.
Yechimni ko'rish
<style> body { font-family: sans-serif; } </style>
<h3>Mevalar</h3>
<ul id="royxat"></ul>
<script>
const mevalar = ["olma", "anor", "uzum"];
const royxat = document.querySelector("#royxat");
for (const meva of mevalar) {
const li = document.createElement("li");
li.textContent = meva;
royxat.append(li);
}
</script>
Massivga "behi" ni qo'shib ko'ring — ro'yxatda to'rtinchi band paydo bo'ladi (tekshiruv esa aynan uchta meva kutgani uchun «Hali to'g'ri emas» deydi — bu normal).
O'zingizni sinang
DOM nima?
- Sahifaning CSS fayli
- JavaScript'ning bir turi
- Brauzer HTML'dan yasaydigan obyektlar daraxti
- Serverdagi ma'lumotlar bazasi
To'g'ri. DOM — sahifaning brauzer xotirasidagi daraxt ko'rinishi; JavaScript uni o'zgartirsa, sahifa ham o'zgaradi.
document.querySelector(".yoq") sahifada bunday element bo'lmasa, nima qaytaradi?
null0- Bo'sh satr
"" - Xato chiqarib, dasturni to'xtatadi
To'g'ri. querySelector o'zi xato bermaydi — null qaytaradi. Xato keyin, null bilan ishlamoqchi bo'lganda chiqadi.
CSS'dagi background-color JavaScript'da qanday yoziladi?
style.background-colorstyle.BackgroundColorstyle["background color"]style.backgroundColor
To'g'ri. Chiziqcha olib tashlanadi, keyingi harf katta bo'ladi — camelCase.
Foydalanuvchi forma maydoniga yozgan matnni sahifaga chiqarishda qaysi biri xavfsiz?
innerHTMLtextContent- Ikkalasi ham bir xil xavfsiz
- Ikkalasi ham xavfli
To'g'ri. textContent teglarni oddiy matn sifatida ko'rsatadi, shuning uchun begona kod ishga tushmaydi.
<head> dagi skript document.querySelector("h1") bilan sarlavhani topa olmayapti, lekin sahifada <h1> bor. Sabab nima?
- Sahifada faqat bitta skript bo'lishi mumkin
h1ni faqatgetElementByIdtopa oladi- Skript ishlaganda
h1hali o'qilmagan edi - Brauzer eskirgan
To'g'ri. Skriptni <body> oxiriga qo'ying yoki tashqi faylni defer bilan ulang.
Xulosa
- DOM — brauzer HTML'dan quradigan obyektlar daraxti. JavaScript uni o'zgartirsa, sahifa darhol yangilanadi.
- Topish:
querySelector(birinchisi),querySelectorAll(hammasi),getElementById. Topilmasa —null. - Matn:
textContent(xavfsiz),innerHTML(HTML sifatida — faqat ishonchli matn uchun), maydonlar uchunvalue. - Uslub:
style.backgroundColor(camelCase), lekin yaxshisi —classList.add / remove / toggle. - Atributlar:
getAttribute,setAttribute. - Yangi element:
createElement→ to'ldirish →append; o'chirish —remove(). - Skript elementlardan keyin ishlashi kerak:
<body>oxirida yokideferbilan.