webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Tooling
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Forms
  12. 12Data and backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animations
  16. 16Testing
  17. 17Architecture
JavaScript · Lesson 17 of 17

DOM and events

Selecting, safe updates, events and event delegation.

Updated

What the DOM is

The DOM (Document Object Model) is the page represented as a tree of objects that JavaScript can read and change. The browser builds it from the HTML; when you change it from JS, the page updates.

  • document
    • html
      • head
      • body
        • header
        • main
          • ul
            • li"Apple"
            • li"Pear"

The HTML is the initial text; the DOM is the live state of the page. If JS adds an <li>, it shows up in the DOM (and in DevTools → Elements), but not in "View source".

Node types

Node Example
document the root
element <li>, <button>
text the text inside an element
comment <!-- -->

In practice you work almost only with elements.

Selecting

Method Returns When
querySelector(css) the first element or null the default — accepts any CSS selector
querySelectorAll(css) a (static) NodeList several elements; [...list] to use map
getElementById(id) one element fast, by id
el.closest(css) the nearest ancestor (or the element itself) event delegation

Changing things

el.textContent = 'Safe text'           // ✓ text, doesn't interpret HTML
el.innerHTML = '<b>HTML</b>'           // ⚠️ interprets HTML — XSS with user data
el.classList.add('active')             // .remove / .toggle / .contains
el.dataset.id                          // reads data-id="..."
el.setAttribute('aria-expanded', 'true')
el.style.setProperty('--progress', '40%')
parent.append(child); el.remove()

textContent vs innerHTML: the first is for text (safe), the second for trusted HTML. The difference is security — see XSS.

Events

An event is a signal that something happened: a click, a key, a submit, a scroll. You listen to it with a listener:

button.addEventListener('click', event => {
  console.log(event.target)       // the element that was clicked
})
Kind Examples
mouse / pointer click, pointerdown, mouseenter
keyboard keydown, keyup
form submit, input, change, focus, blur
window resize, scroll, load

Propagation: capture and bubbling

A click on an <li> isn't just the <li>'s. The event travels down from document to the <li> (capture), then climbs back up (bubbling) through ul, main, body… Every listener along the way receives it.

Property / method Role
event.target the element where it happened (the deepest one)
event.currentTarget the element that has the listener
event.preventDefault() stops the default behavior (a submit, following a link)
event.stopPropagation() stops the climb (rarely needed)

Event delegation

Thanks to bubbling, you put a single listener on the parent instead of one on every child:

list.addEventListener('click', e => {
  const item = e.target.closest('[data-id]')
  if (item) remove(item.dataset.id)
})

It also works for elements added later, and it uses less memory.

Forms

form.addEventListener('submit', e => {
  e.preventDefault()                                // no reload
  const data = Object.fromEntries(new FormData(e.currentTarget))
})

The connection to React

React builds and updates the DOM for you, declaratively: you describe what the UI should look like, React makes the changes. But onClick, event.target, preventDefault, FormData, bubbling — they're exactly the same APIs. React even uses event delegation at the app's root.

Summary

  • The DOM = the page's live tree, changeable from JS.
  • querySelector + closest; textContent for text, innerHTML only with trusted HTML.
  • Events bubble up → delegation with one listener on the parent.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.