DOM — createElement, appendChild, innerHTML, textContent

~20 daq · JavaScript · Brauzer API lari

Muammodan boshlaylik

Serverdan foydalanuvchilar ro'yxati keldi. Ularni sahifada ko'rsatish kerak. HTML da yozib qo'yib bo'lmaydi — ma'lumot dinamik, har safar boshqa.

JavaScript orqali HTML elementlarni yaratish va sahifaga qo'shish kerak. Bu — DOM manipulyatsiya.


textContent — matn o'zgartirish

Elementning matnini o'zgartirish — eng sodda operatsiya.

<h1 id="sarlavha">Eski sarlavha</h1>
const sarlavha = document.getElementById("sarlavha");
sarlavha.textContent = "Yangi sarlavha";

textContent — elementning ichidagi matnni o'qiydi yoki o'zgartiradi. HTML teglar emas — faqat xom matn.

Hayotiy o'xshatma

Maktab taxtasi. Ustidagi yozuvni artib, yangi yozuv yozdingiz. Taxta o'zgarmadi — faqat undagi matn o'zgardi. textContent — o'sha artib qayta yozish.

// O'qish
const tugma = document.querySelector(".tugma");
console.log(tugma.textContent); // "Yuborish"

// O'zgartirish
tugma.textContent = "Yuborildi ✓";

innerHTML — HTML bilan o'zgartirish

innerHTML — element ichiga HTML matn yozish. textContent dan farqi: innerHTML HTML teglarini ham tushunadi va ularni haqiqiy elementlarga aylantiradi.

const konteyner = document.querySelector(".konteyner");

konteyner.innerHTML = `
  <h2>Yangi sarlavha</h2>
  <p>Bu paragraf <strong>qalin</strong> so'z bilan.</p>
`;

Nima uchun textContent emas, innerHTML?

textContent — faqat matn. <strong> kabi teglar ham matn sifatida ko'rsatiladi. innerHTML — HTML ni tushunadi, teglar haqiqiy elementga aylanadi.

const el = document.querySelector("p");

el.textContent = "Bu <strong>qalin</strong>"; // ko'rsatadi: Bu <strong>qalin</strong>
el.innerHTML   = "Bu <strong>qalin</strong>"; // ko'rsatadi: Bu **qalin**

innerHTML ning xavfi — XSS

innerHTML ga foydalanuvchi kiritgan matnni to'g'ridan qo'shsangiz — XSS (Cross-Site Scripting) hujumiga yo'l ochiladi. Foydalanuvchi <script>alert('hacked')</script> kiritse — u ishlaydi.

// ❌ — xavfli
const qidiruv = foydalanuvchi_kiritgani; // "<script>zarar_kodi()</script>"
konteyner.innerHTML = `Qidiruv: ${qidiruv}`; // zarar kod ishlaydi!

// ✅ — xavfsiz: foydalanuvchi matni textContent orqali
const matn = document.createTextNode(foydalanuvchi_kiritgani);
konteyner.textContent = `Qidiruv: ${foydalanuvchi_kiritgani}`;

Qoida: foydalanuvchi kiritgan matnni hech qachon innerHTML ga qo'ymaslik.


createElement — yangi element yaratish

innerHTML eski usul — ichidagi hamma narsani o'chirib qayta yozadi. Yangi element yaratib qo'shish — aniqroq va xavfsizroq.

const tugma = document.createElement("button"); // ← <button></button> yaratildi

Yaratilgan element hozircha "havoda" — sahifada ko'rinmaydi. Unga xususiyatlar berib, keyin sahifaga qo'shish kerak.

const tugma = document.createElement("button");

tugma.textContent  = "Bosing";           // ← matn
tugma.className    = "btn btn-primary";  // ← sinf
tugma.id           = "asosiy-tugma";     // ← id
tugma.disabled     = false;              // ← xususiyat

// Atribut qo'shish
tugma.setAttribute("data-id", "42");

appendChild va append — sahifaga qo'shish

Element yaratildi. Uni sahifaga qo'shish uchun — ota elementga "farzand" sifatida qo'shish kerak.

Hayotiy o'xshatma

Stol quryapsiz. Oyoqlarni, taxtani alohida yasadingiz — ular hozircha alohida turgan detallar. Qo'shish — ularni biriktirib, haqiqiy stolga aylantirish.

const ro_yxat  = document.querySelector("ul");
const yangi_li = document.createElement("li");

yangi_li.textContent = "Yangi element";

ro_yxat.appendChild(yangi_li); // ← ul ichiga li qo'shildi

append — zamonaviyroq, bir vaqtda bir nechta element yoki matn qo'shish mumkin:

const konteyner = document.querySelector(".konteyner");

const sarlavha  = document.createElement("h2");
const paragraf  = document.createElement("p");

sarlavha.textContent = "Sarlavha";
paragraf.textContent = "Matn";

konteyner.append(sarlavha, paragraf, "oddiy matn ham"); // ← bir vaqtda uch narsa

Ro'yxat yaratish — amaliy misol

Serverdan kelgan ma'lumotni DOM ga aylantirish:

const foydalanuvchilar = [
  { id: 1, ism: "Jasur",  email: "jasur@mail.com"  },
  { id: 2, ism: "Malika", email: "malika@mail.com" },
  { id: 3, ism: "Sardor", email: "sardor@mail.com" },
];

const ro_yxat = document.querySelector("#foydalanuvchilar");

foydalanuvchilar.forEach(function(f) {
  const li    = document.createElement("li");
  const ism   = document.createElement("strong");
  const email = document.createElement("span");

  ism.textContent   = f.ism;
  email.textContent = ` — ${f.email}`;

  li.append(ism, email);
  ro_yxat.appendChild(li);
});

Natija:

<ul id="foydalanuvchilar">
  <li><strong>Jasur</strong><span> — jasur@mail.com</span></li>
  <li><strong>Malika</strong><span> — malika@mail.com</span></li>
  <li><strong>Sardor</strong><span> — sardor@mail.com</span></li>
</ul>

Ko'p element qo'shishda — DocumentFragment

Har safar appendChild chaqirilganda — brauzer sahifani qayta hisoblaydi (reflow). 100 ta element qo'shsangiz — 100 marta qayta hisoblaydi. Bu sekin.

DocumentFragment — xotiradagi "vaqtinchalik konteyner". Hamma elementlar unga qo'shiladi, keyin bir marta sahifaga qo'shiladi — bitta reflow.

const fragment = document.createDocumentFragment();

foydalanuvchilar.forEach(function(f) {
  const li = document.createElement("li");
  li.textContent = f.ism;
  fragment.appendChild(li); // ← sahifada emas, xotirada
});

ro_yxat.appendChild(fragment); // ← bitta qadam bilan sahifaga

Nima uchun bu tezroq?

100 ta appendChild — 100 ta reflow. DocumentFragment bilan — 1 ta reflow. Katta ro'yxatlarda farq sezilarli bo'ladi.


Element o'chirish — remove

const eskilElement = document.querySelector(".eski");
eskilElement.remove(); // ← sahifadan o'chirildi

Ota elementdan o'chirish:

const ota   = document.querySelector(".konteyner");
const bola  = document.querySelector(".konteyner .element");

ota.removeChild(bola);

Tez-tez uchraydigan xatolar

innerHTML ga foydalanuvchi kiritmasini qo'yish:

Bu eng xavfli xato — XSS. Foydalanuvchi kiritgan har qanday matn textContent orqali qo'yilishi kerak.

// ❌ — xavfli
el.innerHTML = foydalanuvchi_kiritgani;

// ✅ — xavfsiz
el.textContent = foydalanuvchi_kiritgani;

Har bir qo'shishda reflow — katta ro'yxatlarda sekin:

// ❌ — 1000 marta reflow
for (let i = 0; i < 1000; i++) {
  const li = document.createElement("li");
  li.textContent = i;
  ro_yxat.appendChild(li); // ← har safar sahifa qayta hisoblanadi
}

// ✅ — 1 marta reflow
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const li = document.createElement("li");
  li.textContent = i;
  fragment.appendChild(li);
}
ro_yxat.appendChild(fragment);

innerHTML ni tozalash uchun ishlatish:

innerHTML = "" — ichidagi elementlarni o'chiradi. Lekin ulardagi event listener lar xotirada qoladi. replaceChildren() yoki remove() afzal.

// ❌ — event listener lar xotirada qolishi mumkin
konteyner.innerHTML = "";

// ✅
konteyner.replaceChildren(); // ← hamma farzandlarni tozalaydi

Xulosa

textContent — elementning matnini o'qish yoki o'zgartirish. HTML teglar ko'rinmaydi — xavfsiz.

innerHTML — HTML bilan o'zgartirish. Foydalanuvchi kiritmasini hech qachon innerHTML ga qo'ymaslik — XSS xavfi.

createElement — yangi element yaratish. Hali sahifada yo'q — xususiyatlar berib, keyin qo'shish.

appendChild / append — sahifaga qo'shish. Ko'p element uchun DocumentFragment — bitta reflow.


Keyingi dars

45-dars: DOM — addEventListener, removeEventListener, event ob'ekti