Lesson 2: DOM & events
Learn what the DOM is, how to select and update elements, and how to respond to user events.
Learning goals
- Understand the DOM as an HTML tree you can read and change
- Select elements with getElementById, querySelector, querySelectorAll
- Read & update content with textContent, classList, and style
- Handle events (click, input, submit) using addEventListener
- Prevent default form submission with event.preventDefault()
DOM basics
The DOM (Document Object Model) is the browser's representation of the HTML document as a tree of nodes. You can read and modify nodes with JavaScript.
<div id="count">0</div>
// JS
const countEl = document.getElementById('count');
countEl.textContent = '1';
Selectors:
document.getElementById('id')— fast, returns one element.document.querySelector(selector)— returns first matching element (CSS selector).document.querySelectorAll(selector)— returns a NodeList of matches (iterate with forEach).
Reading & updating
Common ways to read or change elements:
el.textContent— plain text content (use for accessibility and safety).el.classList.add('name')/remove/toggle— preferred for styling changes.el.style.property = 'value'— inline style; use sparingly.
// update text
const title = document.querySelector('.title');
title.textContent = 'New text';
// toggle class
title.classList.toggle('highlight');
// inline style (less preferred)
title.style.color = 'red';
Events explained
Events are things that happen (clicks, typing, form submission). You attach handlers that run when an event fires.
// button click handler
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(event){
console.log('clicked');
});
// input event
const input = document.querySelector('#name');
input.addEventListener('input', function(e){
console.log(e.target.value);
});
Form submit + preventDefault
Forms submit and reload the page by default. Use event.preventDefault() to stop it and handle data in JS.
<form id="myform">
<input id="msg" name="msg">
<button type="submit">Send</button>
</form>
// JS
const form = document.getElementById('myform');
form.addEventListener('submit', function(e){
e.preventDefault();
const value = document.getElementById('msg').value;
console.log(value);
});
Patterns & best practices
- Cache element references in variables to avoid repeated lookups.
- Write small functions that do one job (update UI, handle data).
- Prefer
classListover inlinestylefor styling changes. - Place scripts at end of body or use DOMContentLoaded to ensure elements exist.
Common mistakes
- Selecting elements before they exist — either put scripts after HTML or wait for DOMContentLoaded.
- Using wrong selectors — check the DOM structure and classes/ids.
- Assuming querySelectorAll returns an Array — it's a NodeList (use forEach or Array.from).
- Using
innerHTMLunnecessarily — prefertextContentwhen inserting plain text.
Practice tasks
- Build a counter: a button increases a number displayed on the page.
- Toggle a class on an element to show/hide or highlight it.
- Make a form that shows a message below it without reloading the page.
Code examples
// Counter example (minimal)
<button id="inc">+1</button>
<div id="count">0</div>
// JS
const inc = document.getElementById('inc');
const count = document.getElementById('count');
let n = 0;
inc.addEventListener('click', () => { n++; count.textContent = n; });
// Toggle class
const box = document.querySelector('.box');
const tgl = document.getElementById('toggle');
tgl.addEventListener('click', () => box.classList.toggle('active'));
// Form submit with preventDefault
const formEl = document.getElementById('myform');
formEl.addEventListener('submit', function(e){
e.preventDefault();
const v = document.getElementById('msg').value.trim();
document.getElementById('result').textContent = v;
});