Hujjatni o'zgartirish
DOM'ni o'zgartirish โ bu "jonli" sahifalar yaratishning kalitidir. Ushbu darsda biz sahifaga yangi elementlarni qanday yaratish va joylashtirishni, mavjudlarini o'chirish yoki almashtirishni chuqur o'rganamiz. Barcha zamonaviy va eski usullarni birma-bir ko'rib chiqamiz.
Misol uchun HTML
Ushbu darsdagi ko'p misollar quyidagi oddiy HTML tuzilmasi bilan ishlaydi โ bu bizga xabar ("ziravor", ya'ni yordamchi eslatma) ko'rsatuvchi element yaratish vazifasini bajaradi:
<style>
.alert {
padding: 15px;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
background-color: #dff0d8;
}
</style>
<div id="div">
<p>Bu sahifada muhim xabar ko'rsatiladi.</p>
</div>
Element yaratish: createElement va createTextNode
Yangi DOM tugunlarini (node) yaratish uchun ikkita asosiy usul mavjud.
document.createElement(tag)
Berilgan teg bilan yangi element tugunini (element node) yaratadi:
let div = document.createElement('div');
document.createTextNode(text)
Berilgan matn bilan yangi matn tugunini (text node) yaratadi:
let textNode = document.createTextNode('Bu yerda matn.');
Ko'pincha element yaratib, unga to'g'ridan-to'g'ri HTML yoki matn kiritish qulayroq bo'ladi. Masalan, xabar elementini quyidagicha tayyorlaymiz:
let div = document.createElement('div');
div.className = 'alert';
div.innerHTML = "<strong>Salom!</strong> Siz muhim xabarni o'qidingiz.";
Biz element yaratdik, unga alert klassini berdik va innerHTML orqali ichki HTML'ini to'ldirdik. Ammo bu element hozircha faqat div o'zgaruvchisida turibdi โ u hali sahifada emas. Uni sahifaga qo'shishimiz kerak.
Kiritish usullari: append, prepend, before, after, replaceWith
Yaratilgan elementni sahifaga qo'shish uchun zamonaviy usullardan foydalanamiz. Aytaylik, ol ro'yxatimiz bor:
<ol id="ol">
<li>0</li>
<li>1</li>
<li>2</li>
</ol>
Quyidagi usullar keng qamrovga ega bo'lib, bir vaqtning o'zida bir nechta tugunlarni yoki matn qatorlarini qo'sha oladi:
node.append(...bolalar)โnodening oxiriga (ichiga) qo'shadi;node.prepend(...bolalar)โnodening boshiga (ichiga) qo'shadi;node.before(...bolalar)โnodedan oldin qo'shadi;node.after(...bolalar)โnodedan keyin qo'shadi;node.replaceWith(...bolalar)โnodeni yangilar bilan almashtiradi.
Quyidagi misol bu usullarning barchasini bir joyda ko'rsatadi:
let ol = document.getElementById('ol');
ol.before('before'); // ol dan oldin 'before' matnini qo'yadi
ol.after('after'); // ol dan keyin 'after' matnini qo'yadi
let liFirst = document.createElement('li');
liFirst.innerHTML = 'prepend';
ol.prepend(liFirst); // ol boshiga liFirst qo'yadi
let liLast = document.createElement('li');
liLast.innerHTML = 'append';
ol.append(liLast); // ol oxiriga liLast qo'yadi
Natijada sahifa quyidagi tuzilmaga ega bo'ladi:
before
<ol id="ol">
<li>prepend</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>append</li>
</ol>
after
Bu usullar bir vaqtning o'zida ixtiyoriy sonli tugun va matn qatorlarini qabul qila oladi. Masalan, matn qatori va element birgalikda:
let div = document.createElement('div');
let p = document.createElement('p');
div.append(p, 'salom', document.createElement('hr'));
// div ichiga: <p>, 'salom' matni va <hr> qo'shildi
< va > belgilar HTML sifatida talqin qilinmaydi, balki ekranga <, > kabi eskeyplangan holda chiqadi. Bu XSS hujumlaridan himoya qiladi.insertAdjacentHTML / Text / Element
Yuqoridagi usullar tugun va matnlarni kiritadi, ammo HTML qatorini xom holda (teglar bilan) kiritish uchun insertAdjacentHTML ishlatiladi.
let div = document.getElementById('div');
div.insertAdjacentHTML('beforebegin', '<p>Salom</p>');
div.insertAdjacentHTML('afterend', '<p>Xayr</p>');
Birinchi argument โ joylashuv (position) qatori bo'lib, quyidagi to'rt qiymatdan biri bo'lishi mumkin:
'beforebegin'โelemdan bevosita oldin;'afterbegin'โelemichida, eng boshiga;'beforeend'โelemichida, eng oxiriga;'afterend'โelemdan bevosita keyin.
Ikkinchi argument โ kiritiladigan HTML qatori bo'lib, u aynan HTML sifatida talqin qilinadi.
Metodning ikkita "birodari" ham mavjud:
elem.insertAdjacentText(position, text)โ sintaksisi bir xil, lekin argument matn bo'lib, xavfsiz (eskeyplab) kiritiladi;elem.insertAdjacentElement(position, elem)โ sintaksisi bir xil, lekin element tugunini kiritadi.
Amaliyotda esa deyarli har doim insertAdjacentHTML ishlatiladi. Elementlar va matn uchun yuqorida ko'rilgan append/prepend/before/after qulayroq va o'qilishi osonroq.
insertAdjacentHTML mavjud elementlarni qayta yaratmaydi โ u yangi HTML'ni parslash orqali kiritadi. Bu innerHTML += dan afzalroq, chunki innerHTML += butun ichki tarkibni o'chirib qayta yaratadi (obyekt havolalari va hodisalar yo'qoladi).Tugunlarni o'chirish: remove
Tugunni o'chirish uchun eng oddiy zamonaviy usul node.remove():
let div = document.getElementById('div');
div.remove(); // div sahifadan olib tashlanadi
E'tibor bering โ agar elementni boshqa joyga ko'chirmoqchi bo'lsak, avval uni o'chirishning hojati yo'q. Kiritish usullari (append, before va h.k.) elementni avtomatik ravishda eski o'rnidan olib, yangi o'ringa qo'yadi:
let first = document.getElementById('first');
let second = document.getElementById('second');
// second ni first dan keyinga ko'chiradi:
// (avval o'chirish shart emas โ u eski o'rnidan avtomatik olinadi)
first.after(second);
Bir xil tugun ikki joyda bir vaqtda tura olmaydi, shuning uchun u har doim eski o'rnidan olib ko'chiriladi.
Nusxalash: cloneNode
Bir xil elementdan yana bir nechtasini yaratmoqchi bo'lsak, uni qo'lda qayta yasash o'rniga nusxalash qulayroq.
elem.cloneNode(true)โ elementning "chuqur" nusxasini yaratadi: barcha atributlari va barcha ichki bolalari bilan birga;elem.cloneNode(false)โ "sayoz" nusxa: element o'zi, atributlari bilan, lekin bolalarsiz.
let div = document.getElementById('div');
let div2 = div.cloneNode(true); // chuqur nusxa
div2.querySelector('strong').innerHTML = 'Salom yana!'; // nusxani o'zgartiramiz
div.after(div2); // nusxani asl div'dan keyin ko'rsatamiz
true) โ bir xil ko'rinishdagi elementlarni tez ko'paytirish uchun juda foydali. Masalan, jadval qatorini bir marta yaratib, uni ko'p marta nusxalab qo'shish mumkin.Eski maktab usullari
Tarixiy sabablarga ko'ra DOM'ni o'zgartirishning eski usullari ham mavjud. Ular hozir ham ishlaydi va eski kodlarda tez-tez uchraydi, shuning uchun ularni bilish muhim.
parent.appendChild(node)โnodeniparentning oxirgi bolasi qilib qo'shadi;parent.insertBefore(node, nextSibling)โnodeniparentichiga,nextSiblingdan oldin qo'shadi;parent.replaceChild(newElem, oldElem)โoldElemninewElemga almashtiradi;parent.removeChild(node)โnodeniparentdan o'chiradi (nodeparentning bolasi bo'lishi kerak).
Masalan, yangi lini ro'yxat oxiriga qo'shish:
let ol = document.getElementById('ol');
let newLi = document.createElement('li');
newLi.innerHTML = 'Salom, dunyo!';
ol.appendChild(newLi); // eski usul
// zamonaviy ekvivalenti: ol.append(newLi);
insertBefore yordamida ro'yxatning boshiga qo'shish:
let ol = document.getElementById('ol');
let newLi = document.createElement('li');
newLi.innerHTML = 'Birinchi!';
ol.insertBefore(newLi, ol.firstChild); // eski usul
// zamonaviy ekvivalenti: ol.prepend(newLi);
Elementni o'chirish:
let div = document.getElementById('div');
div.parentNode.removeChild(div); // eski usul
// zamonaviy ekvivalenti: div.remove();
removeChild uchun ota-elementga (parentNode) murojaat qilish kerak, garchi biz allaqachon o'chiriladigan elementni bilsak ham. Zamonaviy usullar (remove, append va h.k.) qisqaroq va tushunarliroq. Yangi kodda ularni ishlatishga harakat qiling.DocumentFragment
DocumentFragment โ bu tugunlar ro'yxatini o'z ichiga oluvchi maxsus DOM tugunidir. Uni tugunlar guruhi uchun "idish" (o'rovchi) deb tasavvur qilish mumkin. Uni biror joyga kiritganimizda, uning o'zi emas, balki ichidagi bolalari kiritiladi.
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;
}
let ul = document.getElementById('ul');
ul.append(getListContent()); // (*) fragmentning bolalari qo'shiladi
(*) qatorida biz fragmentni qo'shdik, lekin u "eriydi" โ natijada ul ichida shunday tuzilma hosil bo'ladi:
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
DocumentFragment kamdan-kam ishlatiladi, chunki uning o'rniga oddiy massiv ham qaytarish mumkin: ul.append(...arrayOfLi). Biroq fragment ma'lum stsenariylarda, ayniqsa ko'p elementlarni bir marta qo'shishda unumdorlik uchun foydali bo'lishi mumkin.Xulosa
Tugunlar yaratish usullari:
document.createElement(tag)โ teg bilan element tuguni;document.createTextNode(text)โ matn tuguni;elem.cloneNode(deep)โ elementni nusxalash (deep=trueโ bolalari bilan).
Kiritish va o'chirish (zamonaviy):
append,prepend,before,after,replaceWithโ tugun va matnlarni kiritish/almashtirish;removeโ tugunni o'chirish;insertAdjacentHTML/Text/Elementโ HTML qatori yoki tugunni ma'lum joyga kiritish.
Eski usullar: appendChild, insertBefore, replaceChild, removeChild โ ular hamon ishlaydi, ammo zamonaviy usullar afzalroq. DocumentFragment esa tugunlar guruhini birgalikda kiritish uchun maxsus "o'rovchi" vazifasini bajaradi.