6 сентябр 2025

Hujjatni o'zgartirish

DOM ni o’zgartirish “jonli” sahifalar yaratishning kalitidir.

Bu yerda yangi elementlarni “tezkorlik bilan” yaratish va mavjud sahifa kontentini o’zgartirish usullarini ko’rib chiqamiz.

Misol: xabar ko’rsatish

Bir misol bilan ko’rsatib beraylik. Biz sahifaga alertdan ko’ra chiroyliroq ko’rinadigan xabar qo’shamiz.

Qanday ko’rinishi:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<div class="alert">
  <strong>Salom!</strong> Siz muhim xabarni o'qidingiz.
</div>

Bu HTML misoli edi. Endi xuddi shunday div ni JavaScript bilan yaratamiz (uslublar HTML/CSS da allaqachon mavjud deb faraz qilib).

Element yaratish

DOM tugunlarini yaratish uchun ikkita usul mavjud:

document.createElement(tag)

Berilgan teg bilan yangi element tugunini yaratadi:

let div = document.createElement('div');
document.createTextNode(text)

Berilgan matn bilan yangi matn tugunini yaratadi:

let textNode = document.createTextNode('Mana men shu yerdaman');

Ko’pincha bizga xabar uchun div kabi element tugunlarini yaratish kerak.

Xabar yaratish

Xabar div ni yaratish 3 bosqichdan iborat:

// 1. <div> elementini yaratish
let div = document.createElement('div');

// 2. Uning sinfini "alert" ga o'rnatish
div.className = "alert";

// 3. Uni kontent bilan to'ldirish
div.innerHTML = "<strong>Salom!</strong> Siz muhim xabarni o'qidingiz.";

Biz elementni yaratdik. Ammo hozircha u faqat div nomli o’zgaruvchida, sahifada emas. Shuning uchun biz uni ko’ra olmaymiz.

Qo’yish usullari

div ni ko’rsatish uchun uni document ning biror joyiga, masalan document.body orqali havola qilingan <body> elementiga qo’yishimiz kerak.

Buning uchun maxsus append usuli mavjud: document.body.append(div).

Mana to’liq kod:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  let div = document.createElement('div');
  div.className = "alert";
  div.innerHTML = "<strong>Salom!</strong> Siz muhim xabarni o'qidingiz.";

  document.body.append(div);
</script>

Bu yerda biz document.body da append ni chaqirdik, lekin biz append usulini boshqa har qanday elementda ham chaqirib, unga boshqa elementni qo’ya olamiz. Masalan, div.append(anotherElement) ni chaqirib <div> ga biror narsa qo’sha olamiz.

Mana boshqa qo’yish usullari, ular qayerga qo’yishning turli joylarini belgilaydi:

  • node.append(...nodes or strings) – tugunlar yoki satrlarni node ning oxiriga qo’shadi,
  • node.prepend(...nodes or strings) – tugunlar yoki satrlarni node ning boshiga qo’yadi,
  • node.before(...nodes or strings) –- tugunlar yoki satrlarni node dan oldin qo’yadi,
  • node.after(...nodes or strings) –- tugunlar yoki satrlarni node dan keyin qo’yadi,
  • node.replaceWith(...nodes or strings) –- node ni berilgan tugunlar yoki satrlar bilan almashtiradi.

Bu usullarning argumentlari qo’yish uchun DOM tugunlarining ixtiyoriy ro’yxati yoki matn satrlari (ular avtomatik ravishda matn tugunlariga aylanadi).

Ularni amalda ko’rib chiqaylik.

Mana ushbu usullardan foydalanib ro’yxatga elementlar va uning oldidan/orqasidan matn qo’shish misoli:

<ol id="ol">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>

<script>
  ol.before('oldin'); // <ol> dan oldin "oldin" satrini qo'yish
  ol.after('keyin'); // <ol> dan keyin "keyin" satrini qo'yish

  let liFirst = document.createElement('li');
  liFirst.innerHTML = 'prepend';
  ol.prepend(liFirst); // liFirst ni <ol> ning boshiga qo'yish

  let liLast = document.createElement('li');
  liLast.innerHTML = 'append';
  ol.append(liLast); // liLast ni <ol> ning oxiriga qo'yish
</script>

Mana usullar nima qilishining vizual tasviri:

Shunday qilib, yakuniy ro’yxat quyidagicha bo’ladi:

oldin
<ol id="ol">
  <li>prepend</li>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>append</li>
</ol>
keyin

Aytganimizdek, bu usullar bir marta chaqiruvda bir nechta tugunlar va matn qismlarini qo’ya oladi.

Masalan, bu yerda satr va element qo’yiladi:

<div id="div"></div>
<script>
  div.before('<p>Salom</p>', document.createElement('hr'));
</script>

E’tibor bering: matn “matn sifatida” qo’yiladi, “HTML sifatida” emas, <, > kabi belgilar to’g’ri qochib ketiladi.

Shunday qilib, yakuniy HTML:

&lt;p&gt;Salom&lt;/p&gt;
<hr>
<div id="div"></div>

Boshqacha qilib aytganda, satrlar elem.textContent kabi xavfsiz tarzda qo’yiladi.

Shunday qilib, bu usullar faqat DOM tugunlari yoki matn qismlarini qo’yish uchun ishlatilishi mumkin.

Ammo agar biz HTML satrni “HTML sifatida” qo’yishni, barcha teglar va narsalar elem.innerHTML kabi ishlashini istasak-chi?

insertAdjacentHTML/Text/Element

Buning uchun biz boshqa, juda ko’p qirrali usuldan foydalanishimiz mumkin: elem.insertAdjacentHTML(where, html).

Birinchi parametr – elem ga nisbatan qayerga qo’yishni belgilovchi kod so’zi. Quyidagilardan biri bo’lishi kerak:

  • "beforebegin"html ni elem dan darhol oldin qo’yish,
  • "afterbegin"html ni elem ichiga, boshiga qo’yish,
  • "beforeend"html ni elem ichiga, oxiriga qo’yish,
  • "afterend"html ni elem dan darhol keyin qo’yish.

Ikkinchi parametr – “HTML sifatida” qo’yiladigan HTML satr.

Masalan:

<div id="div"></div>
<script>
  div.insertAdjacentHTML('beforebegin', '<p>Salom</p>');
  div.insertAdjacentHTML('afterend', '<p>Xayr</p>');
</script>

…Quyidagiga olib keladi:

<p>Salom</p>
<div id="div"></div>
<p>Xayr</p>

Mana sahifaga ixtiyoriy HTML qo’shish usuli.

Mana qo’yish variantlarining tasviri:

Biz bu bilan oldingi rasm o’rtasidagi o’xshashlikni osongina seza olamiz. Qo’yish nuqtalari aslida bir xil, lekin bu usul HTML qo’yadi.

Usulning ikkita ukasi bor:

  • elem.insertAdjacentText(where, text) – xuddi shunday sintaksis, lekin HTML o’rniga text satri “matn sifatida” qo’yiladi,
  • elem.insertAdjacentElement(where, elem) – xuddi shunday sintaksis, lekin element qo’yiladi.

Ular asosan sintaksisni “bir xil” qilish uchun mavjud. Amalda ko’pincha faqat insertAdjacentHTML ishlatiladi. Chunki elementlar va matn uchun bizda append/prepend/before/after usullari bor – ularni yozish qisqaroq va ular tugunlar/matn qismlarini qo’ya oladi.

Shunday qilib, mana xabar ko’rsatishning muqobil varianti:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  document.body.insertAdjacentHTML("afterbegin", `<div class="alert">
    <strong>Salom!</strong> Siz muhim xabarni o'qidingiz.
  </div>`);
</script>

Tugunni olib tashlash

Tugunni olib tashlash uchun node.remove() usuli mavjud.

Keling, xabarimizni bir soniyadan keyin yo’qolib ketishini ta’minlaylik:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<script>
  let div = document.createElement('div');
  div.className = "alert";
  div.innerHTML = "<strong>Salom!</strong> Siz muhim xabarni o'qidingiz.";

  document.body.append(div);
  setTimeout(() => div.remove(), 1000);
</script>

E’tibor bering: agar biz elementni boshqa joyga ko’chirmoqchi bo’lsak – uni eski joydan olib tashlashning hojati yo’q.

Barcha qo’yish usullari tugunni eski joydan avtomatik ravishda olib tashlaydi.

Masalan, elementlarni almashtiraylik:

<div id="first">Birinchi</div>
<div id="second">Ikkinchi</div>
<script>
  // remove ni chaqirishning hojati yo'q
  second.after(first); // #second ni olib, uning orqasiga #first ni qo'y
</script>

Tugunlarni klonlash: cloneNode

Yana bitta shunga o’xshash xabar qanday qo’yish mumkin?

Biz funksiya yasab, kodni u yerga qo’yishimiz mumkin. Ammo muqobil usul mavjud div ni klonlash va ichidagi matnni o’zgartirish (kerak bo’lsa).

Ba’zan katta elementimiz bo’lsa, bu tezroq va oddiyroq bo’lishi mumkin.

  • elem.cloneNode(true) chaqiruvi elementning “chuqur” klonini yaratadi – barcha atributlar va subelementlar bilan. Agar biz elem.cloneNode(false) ni chaqirsak, klon bola elementlarsiz yaratiladi.

Xabarni nusxalash misoli:

<style>
.alert {
  padding: 15px;
  border: 1px solid #d6e9c6;
  border-radius: 4px;
  color: #3c763d;
  background-color: #dff0d8;
}
</style>

<div class="alert" id="div">
  <strong>Salom!</strong> Siz muhim xabarni o'qidingiz.
</div>

<script>
  let div2 = div.cloneNode(true); // xabarni klonlash
  div2.querySelector('strong').innerHTML = 'Xayr!'; // klonni o'zgartirish

  div.after(div2); // mavjud div dan keyin klonni ko'rsatish
</script>

DocumentFragment

DocumentFragment – tugunlar ro’yxatini uzatish uchun o’ram vazifasini bajaradigan maxsus DOM tugun.

Biz unga boshqa tugunlarni qo’sha olamiz, lekin uni biror joyga qo’yganimizda, uning mazmuni qo’yiladi.

Masalan, quyidagi getListContent <li> elementlari bilan fragment yaratadi, ular keyinroq <ul> ga qo’yiladi:

<ul id="ul"></ul>

<script>
function getListContent() {
  let fragment = new DocumentFragment();

  for(let i=1; i<=3; i++) {
    let li = document.createElement('li');
    li.append(i);
    fragment.append(li);
  }

  return fragment;
}

ul.append(getListContent()); // (*)
</script>

E’tibor bering, oxirgi satrda (*) biz DocumentFragment ni qo’shamiz, lekin u “aralashib ketadi”, shuning uchun natija tuzilmasi quyidagicha bo’ladi:

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

DocumentFragment kamdan-kam aniq ishlatiladi. Nima uchun tugunlar massivini qaytarish o’rniga maxsus turdagi tugunga qo’shish kerak? Qayta yozilgan misol:

<ul id="ul"></ul>

<script>
function getListContent() {
  let result = [];

  for(let i=1; i<=3; i++) {
    let li = document.createElement('li');
    li.append(i);
    result.push(li);
  }

  return result;
}

ul.append(...getListContent()); // append + "..." operatori = do'stlar!
</script>

Biz DocumentFragment ni asosan uning ustida ba’zi tushunchalar borligi sababli eslatamiz, masalan keyinchalik ko’rib chiqadigan template elementi.

Eski uslubdagi qo’yish/olib tashlash usullari

Eski maktab
Ushbu ma'lumotlar eski skriptlarni tushunishga yordam beradi, ammo yangi rivojlanish uchun kerak emas.

Tarixiy sabablarga ko’ra mavjud bo’lgan “eski uslubdagi” DOM manipulyatsiya usullari ham mavjud.

Bu usullar haqiqatan ham qadimiy davrlardan keladi. Hozirda ulardan foydalanishning hech qanday sababi yo’q, chunki append, prepend, before, after, remove, replaceWith kabi zamonaviy usullar moslashuvchanroq.

Biz bu usullarni bu yerda sanab o’tishimizning yagona sababi – ularni ko’plab eski skriptlarda uchrashingiz mumkin:

parentElem.appendChild(node)

node ni parentElem ning oxirgi bolasi sifatida qo’shadi.

Quyidagi misol <ol> ning oxiriga yangi <li> qo’shadi:

<ol id="list">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>

<script>
  let newLi = document.createElement('li');
  newLi.innerHTML = 'Salom, dunyo!';

  list.appendChild(newLi);
</script>
parentElem.insertBefore(node, nextSibling)

node ni parentElem ichida nextSibling dan oldin qo’yadi.

Quyidagi kod ikkinchi <li> dan oldin yangi ro’yxat elementini qo’yadi:

<ol id="list">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>
<script>
  let newLi = document.createElement('li');
  newLi.innerHTML = 'Salom, dunyo!';

  list.insertBefore(newLi, list.children[1]);
</script>

newLi ni birinchi element sifatida qo’yish uchun buni qilishimiz mumkin:

list.insertBefore(newLi, list.firstChild);
parentElem.replaceChild(node, oldChild)

parentElem bolalari orasida oldChild ni node bilan almashtiradi.

parentElem.removeChild(node)

node ni parentElem dan olib tashlaydi (node uning bolasi deb faraz qilib).

Quyidagi misol <ol> dan birinchi <li> ni olib tashlaydi:

<ol id="list">
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ol>

<script>
  let li = list.firstElementChild;
  list.removeChild(li);
</script>

Bu usullarning barchasi qo’yilgan/olib tashlangan tugunni qaytaradi. Boshqacha qilib aytganda, parentElem.appendChild(node) node ni qaytaradi. Ammo odatda qaytarilgan qiymat ishlatilmaydi, biz shunchaki usulni ishga tushiramiz.

“document.write” haqida bir so’z

Veb-sahifaga biror narsa qo’shishning yana bir juda qadimiy usuli mavjud: document.write.

Sintaksis:

<p>Sahifaning biror joyida...</p>
<script>
  document.write('<b>JS dan salom</b>');
</script>
<p>Oxiri</p>

document.write(html) ga chaqiruv html ni sahifaga “aynan shu yerda va hozir” yozadi. html satri dinamik ravishda yaratilishi mumkin, shuning uchun u qandaydir moslashuvchan. Biz JavaScript dan foydalanib to’liq veb-sahifa yaratib, uni yoza olamiz.

Bu usul DOM, standartlar bo’lmagan davrlardan keladi… Haqiqatan ham eski zamonlar. U hali ham mavjud, chunki undan foydalanuvchi skriptlar bor.

Zamonaviy skriptlarda biz uni kamdan-kam ko’ramiz, quyidagi muhim cheklov sababli:

document.write ga chaqiruv faqat sahifa yuklanayotganda ishlaydi.

Agar biz uni keyinroq chaqirsak, mavjud hujjat mazmuni o’chiriladi.

Masalan:

<p>Bir soniyadan keyin ushbu sahifa mazmuni almashtiriladi...</p>
<script>
  // 1 soniyadan keyin document.write
  // bu sahifa yuklangandan keyin, shuning uchun mavjud kontentni o'chiradi
  setTimeout(() => document.write('<b>...Mana bu bilan.</b>'), 1000);
</script>

Shunday qilib, u yuqorida ko’rib chiqilgan boshqa DOM usullaridan farqli ravishda “yuklangandan keyin” bosqichida yaroqsiz.

Bu salbiy tomoni.

Ijobiy tomoni ham bor. Texnik jihatdan, document.write brauzer kiruvchi HTML ni o’qiyotganda (“tahlil qilayotganda”) chaqirilganda va u biror narsa yozganda, brauzer uni xuddi dastlab HTML matnida bo’lgandek qabul qiladi.

Shunday qilib, u juda tez ishlaydi, chunki DOM o’zgartiruvi yo’q. U DOM hali qurilmagan vaqtda to’g’ridan-to’g’ri sahifa matniga yozadi.

Shunday qilib, agar bizga HTML ga dinamik ravishda ko’p matn qo’shish kerak bo’lsa va biz sahifa yuklash bosqichidamiz va tezlik muhim bo’lsa, u yordam berishi mumkin. Ammo amalda bu talablar kamdan-kam uchraydi. Va odatda biz bu usulni skriptlarda shunchaki eski bo’lganligi uchun ko’ramiz.

Xulosa

  • Yangi tugunlar yaratish usullari:

    • document.createElement(tag) – berilgan teg bilan element yaratadi,
    • document.createTextNode(value) – matn tugunini yaratadi (kamdan-kam ishlatiladi),
    • elem.cloneNode(deep) – elementni klonlaydi, agar deep==true bo’lsa barcha avlodlar bilan.
  • Qo’yish va olib tashlash:

    • node.append(...nodes or strings)node ga, oxiriga qo’yish,
    • node.prepend(...nodes or strings)node ga, boshiga qo’yish,
    • node.before(...nodes or strings) –- node dan oldin qo’yish,
    • node.after(...nodes or strings) –- node dan keyin qo’yish,
    • node.replaceWith(...nodes or strings) –- node ni almashtirish.
    • node.remove() –- node ni olib tashlash.

    Matn satrlari “matn sifatida” qo’yiladi.

  • “Eski uslubdagi” usullar ham mavjud:

    • parent.appendChild(node)
    • parent.insertBefore(node, nextSibling)
    • parent.removeChild(node)
    • parent.replaceChild(newElem, node)

    Bu usullarning barchasi node ni qaytaradi.

  • html dagi HTML berilgan bo’lsa, elem.insertAdjacentHTML(where, html) uni where qiymatiga qarab qo’yadi:

    • "beforebegin"html ni elem dan oldin qo’yish,
    • "afterbegin"html ni elem ichiga, boshiga qo’yish,
    • "beforeend"html ni elem ichiga, oxiriga qo’yish,
    • "afterend"html ni elem dan keyin qo’yish.

    Shuningdek, o’xshash usullar elem.insertAdjacentText va elem.insertAdjacentElement mavjud, ular matn satrlari va elementlarni qo’yadi, lekin ular kamdan-kam ishlatiladi.

  • Sahifa yuklanish tugashidan oldin HTML qo’shish uchun:

    • document.write(html)

    Sahifa yuklangandan keyin bunday chaqiruv hujjatni o’chiradi. Asosan eski skriptlarda ko’riladi.

Vazifalar

Bizda bo’sh DOM elementi “elem” va “matn” qatori mavjud.

Ushbu 3 ta buyruqdan qaysi biri xuddi shunday bajaradi?

  1. elem.append(document.createTextNode(text))
  2. elem.innerHTML = text
  3. elem.textContent = text

Javob: 1 va 3.

Ikkala buyruq ham elemga matnni «matn sifatida» qo’shishga olib keladi.

Mana bir misol:

<div id="elem1"></div>
<div id="elem2"></div>
<div id="elem3"></div>
<script>
  let text = "<b>text</b>";

  elem1.append(document.createTextNode(text));
  elem2.innerHTML = text;
  elem3.textContent = text;
</script>

Elementdan hamma narsani olib tashlaydigan “clear(elem)” funksiyasini yarating.

<ol id="elem">
  <li>Hello</li>
  <li>World</li>
</ol>

<script>
  function clear(elem) {
    /* sizning kodingiz */
  }

  clear(elem); // ro'yxatni tozalash
</script>

Birinchidan, buni qanday qilish kerakligini ko’rib chiqamiz:

function clear(elem) {
  for (let i = 0; i < elem.childNodes.length; i++) {
    elem.childNodes[i].remove();
  }
}

Bu ishlamaydi, chunki remove() chaqiruvi elem.childNodes to‘plamini o‘zgartiradi, shuning uchun elementlar har safar 0 indeksidan boshlanadi. Lekin i ortadi va ba`zi elementlar o’tkazib yuboriladi.

for..of sikli ham xuddi shunday qiladi.

To’g’ri variant quyidagilar bo’lishi mumkin:

function clear(elem) {
  while (elem.firstChild) {
    elem.firstChild.remove();
  }
}

Bundan tashqari, xuddi shunday qilishning oddiy usuli bor:

function clear(elem) {
  elem.innerHTML = "";
}

Quyidagi misolda table.remove() chaqiruvi jadvalni hujjatdan olib tashlaydi.

Agar siz uni ishga tushirsangiz, "aaa" matni hali ham ko’rinib turishini ko’rishingiz mumkin.

Nega bunday bo’ladi?

<table id="table">
  aaa
  <tr>
    <td>Test</td>
  </tr>
</table>

<script>
  alert(table); // stol, xuddi shunday bo'lishi kerak

  table.remove();
  // nega hujjatda hali ham aaa bor?
</script>

Vazifadagi HTML noto’g’ri. Bu g’alati narsaning sababi.

Brauzer uni avtomatik ravishda tuzatishi kerak. Lekin <table> ichida matn bo’lmasligi mumkin: spetsifikatsiyaga ko’ra faqat jadvalga xos teglarga ruxsat beriladi. Shunday qilib, brauzer <table> dan * oldin "aaa" ni ko’rsatadi.

Endi stolni olib tashlaganimizda, u qolishi aniq.

Savolga brauzer vositalaridan foydalangan holda DOMni o’rganish orqali osongina javob berish mumkin. Siz <table> oldidan aaa ni ko`rasiz.

HTML standarti yomon HTMLni qanday qayta ishlashni batafsil belgilaydi va brauzerning bunday xatti-harakati to’g’ri.

Foydalanuvchi kiritishidan roʻyxat yaratish uchun interfeysni yozing.

Har bir ro’yxat elementi uchun:

  1. Prompt yordamida foydalanuvchidan uning mazmuni haqida so‘rang.
  2. U bilan <li> yarating va uni <ul>ga qo`shing.
  3. Foydalanuvchi kiritishni bekor qilmaguncha davom eting (Esc tugmasini bosish yoki bo’sh yozuv orqali).

Barcha elementlar dinamik ravishda yaratilishi kerak.

Agar foydalanuvchi HTML-teglarni yozsa, ularga matn sifatida qarash kerak.

Yangi oynada namoyish

<li> kontentini tayinlash uchun textContent dan foydalanishga e`tibor bering.

Yechimni sandbox-da oching.

O’rnatilgan ob’ektdan o’rnatilgan ul/li ro’yxatini yaratuvchi createTree funksiyasini yozing.

Masalan; misol uchun:

let data = {
  Baliq: {
    gulmoh: {},
    salmon: {},
  },

  Daraxt: {
    Katta: {
      sekvoya: {},
      eman: {},
    },
    Gullaydigan: {
      "olma daraxti": {},
      magnolia: {},
    },
  },
};

Sintaksis:

let container = document.getElementById('container');
createTree(container, data); // quti ichida daraxtni yaratadi

Natija (daraxt) quyidagicha ko’rinishi kerak:

Ushbu vazifani hal qilishning ikkita usulidan birini tanlang:

  1. Daraxt uchun HTML yarating va keyin container.innerHTML ga tayinlang.
  2. Daraxt tugunlarini yarating va DOM usullari bilan qo’shing.

Agar ikkalasini ham qila olsangiz ajoyib bo’lardi.

P.S. Daraxtda barglar uchun bo’sh <ul></ul> kabi “qo’shimcha” elementlar bo’lmasligi kerak.

Vazifa uchun sandbox-ni oching.

Ob’ektni yurishning eng oson usuli – rekursiyadan foydalanish.

  1. innerHTML bilan yechim.
  2. DOM bilan yechim.

Uyali ul/li shaklida tashkil etilgan daraxt bor.

Har bir <li>ga uning avlodlari sonini qo’shadigan kodni yozing. Barglarni o’tkazib yuboring (bolalarsiz tugunlar).

Natija:

Vazifa uchun sandbox-ni oching.

Har bir <li> ga matn qo’shish uchun biz ma'lumotlar matn tugunini o’zgartirishimiz mumkin.

Yechimni sandbox-da oching.

createCalendar(elem, year, month) nomli funksiya yarating.

Funksiya chaqirilganda ma’lum yil/oy uchun kalendar yaratishi va uni elem ichiga qo’yishi kerak.

Taqvim jadval bo’lishi kerak, bu erda hafta <tr>, kun esa <td>. Stol usti ish kunlari nomlari bilan <th> bo’lishi kerak: birinchi kun dushanba bo’lishi kerak va shunga o’xshash yakshanbagacha.

Masalan, createCalendar(cal, 2012, 9) cal elementida quyidagi kalendarni yaratishi kerak:

P.S. Bu vazifani bajarish uchun taqvim yaratish kifoya, uni hali bosish mumkin emas.

Vazifa uchun sandbox-ni oching.

Jadvalni qator sifatida yaratamiz: "<table>...</table>" va keyin uni innerHTML ga tayinlaymiz.

Algoritm:

  1. <th> va hafta kunlari nomlari bilan jadval sarlavhasini yarating.
  2. d = new Date(yil, oy-1) sana obyektini yarating. Bu oyning birinchi kuni (JavaScript-da oylar 1 emas, 0 dan boshlanishini hisobga olgan holda).
  3. d.getDay() oyning birinchi kunigacha bo’lgan dastlabki bir nechta katakchalar bo’sh bo’lishi mumkin. Keling, ularni <td></td> bilan to`ldiramiz.
  4. d da kunni oshiring: d.setDate(d.getDate()+1). Agar d.getMonth() hali keyingi oy bo’lmasa, taqvimga yangi katakchani <td> qo’shing. Agar bu yakshanba bo’lsa, yangi qatorni “</tr><tr>” qo’shing.
  5. Agar oy tugagan bo’lsa, lekin jadval qatori hali to’liq bo’lmasa, unga bo’sh <td> qo’shing, uni kvadratga aylantiring.

Yechimni sandbox-da oching.

muhimlik: 4

Quyidagi kabi rangli soat yarating:

Styling uchun HTML/CSS dan foydalaning, JavaScript faqat elementlardagi vaqtni yangilaydi.

Vazifa uchun sandbox-ni oching.

Soat dasturini yaratish

Avval HTML/CSS yarataylik.

Vaqtning har bir komponenti o’zining <span> da ajoyib ko’rinadi:

<div id="clock">
  <span class="hour">hh</span>:<span class="min">mm</span>:<span class="sec"
    >ss</span
  >
</div>

Shuningdek, ularni rangga solish uchun CSS kerak bo’ladi.

update funksiyasi soatni yangilaydi, har soniyada setInterval tomonidan chaqiriladi:

function update() {
  let clock = document.getElementById('clock');
  let date = new Date(); // (*)
  let hours = date.getHours();
  if (hours < 10) hours = '0' + hours;
  clock.children[0].innerHTML = hours;

  let minutes = date.getMinutes();
  if (minutes < 10) minutes = '0' + minutes;
  clock.children[1].innerHTML = minutes;

  let seconds = date.getSeconds();
  if (seconds < 10) seconds = '0' + seconds;
  clock.children[2].innerHTML = seconds;
}

(*) qatorida biz har safar joriy sanani tekshiramiz. setInterval chaqiruvlari ishonchli emas: ular kechikishlar bilan sodir bo’lishi mumkin.

Soatni boshqaradigan funksiyalar:

let timerId;

function clockStart() {
  // soatni ishga tushirish
  if (!timerId) {
    // faqat soat ishlamayotgan bo'lsa yangi interval o'rnatish
    timerId = setInterval(update, 1000);
  }
  update(); // (*)
}

function clockStop() {
  clearInterval(timerId);
  timerId = null; // (**)
}

E’tibor bering, update() ga chaqiruv nafaqat clockStart() da rejalashtiriladi, balki (*) qatorida darhol ishga tushiriladi. Aks holda tashrif buyuruvchi setInterval ning birinchi bajarilishini kutishi kerak bo’ladi. Va o’sha vaqtgacha soat bo’sh bo’ladi.

Shuningdek, clockStart() da yangi intervalni faqat soat ishlamayotgan vaqtda o’rnatish muhim. Aks holda start tugmasini bir necha marta bosish bir nechta parallel intervallarni o’rnatadi. Bundan ham yomoni – biz faqat oxirgi intervalning timerID sini saqlashimiz va boshqalariga havolalarni yo’qotishimiz mumkin. Keyin biz soatni boshqa hech qachon to’xtata olmaymiz! E’tibor bering, soat to’xtatilganda (**) qatorida timerID ni tozalashimiz kerak, shunda uni clockStart() ni ishga tushirish orqali yana ishga tushirish mumkin bo’ladi.

Yechimni sandbox-da oching.

muhimlik: 5

Ikki <li> orasiga <li>2</li><li>3</li> kiritish uchun kodni bu yerga yozing:

<ul id="ul">
  <li id="one">1</li>
  <li id="two">4</li>
</ul>

Agar biror joyga HTML boʻlagini kiritish kerak boʻlsa, insertAdjacentHTML eng mos keladi.

Yechim:

one.insertAdjacentHTML("afterend", "<li>2</li><li>3</li>");
muhimlik: 5

Mana bu jadval:

<table id="table">
  <thead>
    <tr>
      <th>Ism</th>
      <th>Familiya</th>
      <th>Yosh</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John</td>
      <td>Smith</td>
      <td>10</td>
    </tr>
    <tr>
      <td>Pete</td>
      <td>Brown</td>
      <td>15</td>
    </tr>
    <tr>
      <td>Ann</td>
      <td>Lee</td>
      <td>5</td>
    </tr>
    <tr>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
  </tbody>
</table>

Unda ko’proq qatorlar bo’lishi mumkin.

Uni ism ustuni bo`yicha tartiblash uchun kodni yozing.

Vazifa uchun sandbox-ni oching.

Yechim qisqa, ammo biroz qiyin ko’rinishi mumkin, shuning uchun men unga keng sharhlar beraman:

let sortedRows = Array.from(table.tBodies[0].rows) // 1
  .sort((rowA, rowB) =>
    rowA.cells[0].innerHTML.localeCompare(rowB.cells[0].innerHTML)
  );

table.tBodies[0].append(...sortedRows); // (3)

Bosqichma-bosqich algoritm:

  1. <tbody> dan barcha <tr>-ni oling.
  2. Keyin ularni birinchi <td> (ism maydoni) mazmuni bo’yicha taqqoslab tartiblang.
  3. Endi tugunlarni .append(...sortedRows) orqali kerakli tartibda kiriting.

Biz qator elementlarini olib tashlashimiz shart emas, shunchaki “qayta kiritish”, ular eski joyni avtomatik ravishda tark etishadi.

P.S. Bizning holatda, jadvalda aniq <tbody> mavjud, lekin HTML jadvalida <tbody> bo’lmasa ham, DOM tuzilmasi har doim shunday bo’ladi.

Yechimni sandbox-da oching.

O'quv qo'llanma xaritasi

Izohlar

izoh berishdan oldin buni o'qing…
  • Agar sizda nimani yaxshilash kerakligi haqida takliflaringiz bo'lsa - iltimos, GitHub muammosini yuboring yoki izoh berish o'rniga so'rov yuboring.
  • Agar siz maqolada biror narsani tushunolmasangiz - iltimos, batafsilroq ma'lumot bering.
  • Bir nechta so'z so'zlarini kiritish uchun <code> yorlig'ini ishlating, bir nechta satrlar uchun - ularni <pre> yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepen…)