DOM și evenimente
Selectare, modificare sigură, evenimente și event delegation.
Actualizat
Ce este DOM-ul
DOM (Document Object Model) e reprezentarea paginii ca arbore de obiecte pe care JavaScript îl poate citi și modifica. Browserul îl construiește din HTML; când îl schimbi din JS, pagina se actualizează.
documenthtmlheadbodyheadermainulli„Măr”li„Pară”
HTML-ul e textul inițial; DOM-ul e starea vie a paginii. Dacă JS adaugă un <li>, el apare în DOM (și în DevTools → Elements), dar nu în „View source”.
Tipuri de noduri
| Nod | Exemplu |
|---|---|
document |
rădăcina |
| element | <li>, <button> |
| text | textul dintr-un element |
| comentariu | <!-- --> |
În practică lucrezi aproape doar cu elemente.
Selectare
| Metodă | Returnează | Când |
|---|---|---|
querySelector(css) |
primul element sau null |
implicit — acceptă orice selector CSS |
querySelectorAll(css) |
NodeList (static) |
mai multe elemente; [...list] pentru map |
getElementById(id) |
un element | rapid, după id |
el.closest(css) |
cel mai apropiat strămoș (sau el însuși) | event delegation |
Modificare
el.textContent = 'Text sigur' // ✓ text, nu interpretează HTML
el.innerHTML = '<b>HTML</b>' // ⚠️ interpretează HTML — XSS cu date de la user
el.classList.add('active') // .remove / .toggle / .contains
el.dataset.id // citește data-id="..."
el.setAttribute('aria-expanded', 'true')
el.style.setProperty('--progress', '40%')
parent.append(child); el.remove()textContent vs innerHTML: primul e pentru text (sigur), al doilea pentru HTML de încredere. Diferența e securitatea — vezi XSS.
Evenimente
Un eveniment e un semnal că s-a întâmplat ceva: click, tastă, submit, scroll. Îl asculți cu un listener:
button.addEventListener('click', event => {
console.log(event.target) // elementul pe care s-a dat click
})| Tip | Exemple |
|---|---|
| mouse / pointer | click, pointerdown, mouseenter |
| tastatură | keydown, keyup |
| formular | submit, input, change, focus, blur |
| fereastră | resize, scroll, load |
Propagarea: capture și bubbling
Un click pe un <li> nu e doar al lui. Evenimentul coboară din document până la <li> (capture), apoi urcă înapoi (bubbling) prin ul, main, body… Orice listener de pe drum îl primește.
| Proprietate / metodă | Rol |
|---|---|
event.target |
elementul unde s-a întâmplat (cel mai adânc) |
event.currentTarget |
elementul care are listener-ul |
event.preventDefault() |
oprește comportamentul implicit (submit, navigare la link) |
event.stopPropagation() |
oprește urcarea (rar e nevoie) |
Event delegation
Datorită bubbling-ului, pui un singur listener pe părinte în loc de câte unul pe fiecare copil:
list.addEventListener('click', e => {
const item = e.target.closest('[data-id]')
if (item) remove(item.dataset.id)
})Merge și pentru elemente adăugate ulterior, și consumă mai puțină memorie.
Formulare
form.addEventListener('submit', e => {
e.preventDefault() // fără reload
const data = Object.fromEntries(new FormData(e.currentTarget))
})Legătura cu React
React construiește și actualizează DOM-ul pentru tine, declarativ: tu descrii cum trebuie să arate UI-ul, React face modificările. Dar onClick, event.target, preventDefault, FormData, bubbling-ul — sunt exact aceleași API-uri. React folosește chiar event delegation la rădăcina aplicației.
Pe scurt
- DOM = arborele viu al paginii, modificabil din JS.
querySelector+closest;textContentpentru text,innerHTMLdoar cu HTML de încredere.- Evenimentele urcă (bubbling) → delegation cu un listener pe părinte.