Document Object Model 23.11.20
A DOM egy olyan API ami leírja nekünk a HTML oldalunkat ES-ben egy objectként. Ezen az objektumon keresztül tudjuk az oldalunkat elérni, bejárni és módosítani.
Amit kapunk azok a különböző elemek (Elements) és a Node-ok lesznek amikkel dolgozni tudunk.
Az elemek a tényleges HTML tag-ek alapján készülnek el, míg a node-ba a különböző szöveges tartalmak is beleszólnak.
<p>Hello
<li>Mom
<li>and
<li>Dad

Elemek kiválasztása
Az elemeket elérhetjük különböző tulajdonságaik alapján, mint például osztály vagy azonosító.
getElementsByTagName és getElementsByClassName alapján MINDIG tömbhöz hasonló adatszerkezetet kapunk vissza!const keresettID = "section-4";
const keresettOsztaly = "text-mute";
const keresettTag = "h1";
let elem1 = document.getElementById(keresettID);
let elemek2 = document.getElementsByClassName(keresettOsztaly);
let elemek3 = document.getElementsByTagName(keresettTag);
Azonban van egy egyszerűbb mód is, amivel a CSS selectorok segítségével tudjuk a megfelelő elemet lekérdezni. Ez azonban nagyobb kódban lassabb ez a megoldás.
const egyediCSS = "h1#main-title";
const tobbszorosCSS = ".btn.btn-primary";
let elem4 = document.querySelector(egyediCSS);
let elemek5 = document.querySelectorAll(tobbszorosCSS);
Attribútumok kezelése
A leggyakoribb attribútumokat közvetlenül tudjuk kezelni.
elem.id = "";
image.src = "";
Azonban előfordulhat olyan egyéni attribútum melyet nem tudunk így megadni, ilyenkor a következőképpen tudjuk állítani vagy lekérdezni ezeket:
elem.setAttribute("lang", "HU-hu")
elem.getAttribute("lang")
Stílusok esetében át kell írni a CSS stílusról ES-re. Tehát a kötőjeleket eltávolítva, minden új szó kezdő betűje nagy.
elem.style.backgroundColor = "#ffaadd";
Az osztályok kezelése egy kicsit trükkösebb azonban
elemek.classList.add("d-block")
elemek.classList.remove("d-none")
elemek.classList.replace("d-none", "d-block")
Csere esetén mindig azt adjuk meg, hogy mit és mire cserélünk.
Elemek létrehozása és csatolása
Az objektumunknak van egy speciális függvénye, ami egy HTML elemet tud létrehozni, éppen ezért paraméternek mindig egy HTML tag elnevezését kapja meg.
const ujBekezd = document.createElement("p");
Hozzáfűzni bármelyik elemhez tudunk a végére az append valamint az elejére a prepend függvényen keresztül, ahol
vesszővel vagy kibontott listával több elemet is hozzá tudunk adni gyerekként.
appendChild és a prependChild is amely csak 1 darab elemet tud egyszerre hozzáadni.document.body.append(ujBekezd);
const elemek = [...
..]
;
document.body.append(...elemek);
Elemek körbejárása
Node-okkal
Képesek vagyunk egy elemet úgy körbejárni, hogy az különböző node-okat is belevesszük az elemek közé. Ekkor a szülő és a gyerekek esetén egyszerű a történet, ugyanis megjelöljük, hogy node-ról van szó.
const parent = elem.parentNode;
const childen = elem.childNodes;
Amikor azonban a szomszédokat kérdezzük le, akkor már nem ennyire egyszerű a feladatunk. Itt már nem fog utalni semmi
arra, hogy node is lehet a szomszéd. Pedig nagy valószínűséggel a szomszéd elem helyett egy #text node-ot fogunk
magunk mellett találni.
const previous = elem.previousSibling;
const next = elem.nextSibling;
Ugyanígy, ha az első és utolsó gyereket szeretnénk megkapni, akkor a gyerekekkel szemben itt sem jelöljük meg.
const firstChild = elem.firstChild;
const lastChild = elem.lastChild;
Csak elemekkel
Ha csak a HTML tagek alapján létrehozott elemekről van szó, akkor már sokkal egyszerűbb dolgunk van, ugyanis a gyereken kívül mindegyik esetben megjelöljük, hogy egy elemről lesz szó.
const parentTag = elem.parentElement;
const childrenTag = elem.children;
const previousTag = elem.previousElementSibling;
const nextTag = elem.nextElementSibling;
const firstChildTag = elem.firstElementChild;
const lastChildTag = elem.lastElementChild;
Template-ek
template mint HTML tag
<template>
<p><p>
<template>
Bármilyen a <template> tag-ek közé elhelyezett elem egy speciális szerkezetet fog alkotni. A böngésző az így elkészült
taget nem fogja kirenderelni, csak megjegyzi nekünk, hogy lett egy olyan elemünk ami alkalmas arra, hogy többszörözzük.
Így a fenti példában látható bekezdést szabadon tudjuk másolgatni majd.
Felhasználás ES-ben
Ahhoz, hogy a template-ünk valóban felhasználható legyen egy kis trükköt kell alkalmaznunk.
let template = document.getElementsByTagName("template")[0];
let templateContent = template.content.querySelector("p");
Az így létrejövő templateContent változó lesz a számunkra hasznos, ezt fogjuk másolgatni.
let masolat = document.importNode(templateContent, true);
masolat.innerText = "Szoveg"
document.body.appendChild(masolat);
Itt a DOM előállítja nekünk a <template>-ben szereplő elem(ek)et. A true-ra azért lesz szükségünk, hogy egy
bonyolultabb elem esetén a gyerekeket is másolja.
Többszintű template
<template>
<div>
<h1></h1>
<p></p>
</div>
</template>
let template = document.getElementsByTagName("template")[0];
let templateContent = template.content.querySelector("div");
let masolat = document.importNode(templateContent, true);
masolat.querySelector("h1").innerText = "Cím"
masolat.querySelector("p").innerText = "Szöveg"
document.body.appendChild(masolat);
Példa
Írassuk ki bootstrapes kártyákra a városokat, jelenítsük meg a képét, valamint a gombra kattintva hozza be a város honlapját!
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/bootstrap5.min.css">
</head>
<body>
<template>
<div class="card">
<img class="img-card-top">
<div class="card-body">
<h5></h5>
</div>
<div class="card-footer">
<a class="btn btn-primary">Honlap megnyitasa</a>
</div>
</div>
</template>
<script src="main.js"></script>
</body>
</html>
let varosok = [
{nev:"Budapest", honlap:"https://budapest.hu", kep:"img/budapest.png"},
{nev:"Debrecen", honlap:"https://debrecen.hu", kep:"img/debrecen.png"},
{nev:"Pecs", honlap:"https://pecs.hu", kep:"img/pecs.png"},
{nev:"Gyor", honlap:"https://gyor.hu", kep:"img/gyor.png"},
{nev:"Szeged", honlap:"https://szeged.hu", kep:"img/szeged.png"},
];
let template = document.getElementsByTagName("template")[0];
let templateContent = template.content.querySelector("div.card");
for(let varos of varosok){
let varosKartya = document.importNode(templateContent,true);
varosKartya.querySelector("h5").innerText = varos.nev;
varosKartya.querySelector("img").src = varos.kep;
varosKartya.querySelector("a").href = varos.honlap;
document.body.append(varosKartya);
}
\pagebreak