TEC-WEB46-02 · Lesson 9 · 16 clock hours · lab
DOM Manipulation and Event Handling
Objective. Students select DOM elements using querySelector and querySelectorAll, modify element content and attributes, create and append new elements, and attach event listeners to respond to user interactions.
⚠ Pending professional review
This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.
VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.
What Is the DOM?
When a browser loads an HTML file, it parses the markup and builds a tree of objects in memory called the Document Object Model (DOM). Every HTML element becomes a node in that tree. JavaScript can read and change those nodes at any time, so the page can update without reloading. This is the foundation of all interactive web applications.
Selecting Elements
The two most useful selection methods are `document.querySelector` and `document.querySelectorAll`.
- `document.querySelector('#main-heading')` returns the first element that matches the CSS selector, or `null` if nothing matches.
- `document.querySelectorAll('.card')` returns a NodeList of every matching element. Loop over it with `forEach`.
- `document.getElementById('login-form')` is an older method still widely used; it returns the element whose `id` attribute matches the string.
Always check that a result is not `null` before acting on it. Calling a method on `null` throws a `TypeError` that stops your script.
Modifying Content and Attributes
Once you have an element reference, you can change what users see:
- `element.textContent` sets or reads the plain text inside an element. This is safe for displaying user-supplied data because the browser never interprets it as HTML.
- `element.innerHTML` sets or reads the raw HTML inside an element. It is powerful but dangerous with user input — an attacker can inject a `<script>` tag or an event-handler attribute, a technique called Cross-Site Scripting (XSS). Only use `innerHTML` with content you fully control; never insert raw user input through it.
- `element.setAttribute('href', 'https://example.com')` sets any HTML attribute by name.
- `element.classList.add('active')` adds a CSS class. `classList.remove('active')` removes it. `classList.toggle('active')` adds it when absent and removes it when present — perfect for toggling states.
Creating and Appending Elements
You can build new elements entirely in JavaScript:
```js
const li = document.createElement('li'); // create the node
li.textContent = 'Buy groceries'; // set its text safely
document.querySelector('#task-list').appendChild(li); // add to the page
```
`appendChild` inserts the new node as the last child of the target. `prepend` inserts it as the first child. `insertAdjacentElement` gives even finer control.
Event Listeners
Events are signals the browser sends when the user or the page does something — clicks a button, submits a form, presses a key, or the page finishes loading.
Attach a listener with `addEventListener`:
```js
const btn = document.querySelector('#add-btn');
btn.addEventListener('click', function (event) {
console.log('Button clicked');
});
```
The first argument is the event type string (`'click'`, `'submit'`, `'keydown'`, etc.). The second argument is a callback function that receives an event object. The event object carries useful information: `event.target` is the element that triggered the event, and for forms, `event.preventDefault()` stops the default browser action (such as reloading the page on submit).
Event Propagation: Bubbling and Capturing
When an event fires on a nested element, it does not stay there. By default, it bubbles upward through every ancestor node until it reaches the document root. So a click on a `<button>` inside a `<li>` inside a `<ul>` triggers click handlers on all three elements.
Capturing is the reverse phase: before bubbling, the browser travels down from the root to the target, notifying any listeners registered with `{capture: true}`.
This behavior sometimes causes conflicts — for example, a click on a delete button also fires the list item's click handler. Calling `event.stopPropagation()` inside a handler prevents the event from traveling further, solving the conflict.
Security Note: XSS
Cross-Site Scripting is consistently listed among the most common and harmful web vulnerabilities. The rule is simple: never pass user-controlled text to `innerHTML`, `document.write`, or any property that interprets HTML. Use `textContent` or `createTextNode` instead. This is not optional — it is a professional and ethical responsibility.
Using Chrome DevTools
The Elements panel lets you inspect the live DOM tree. Click any element to see its current attributes and computed styles. The Console panel lets you run JavaScript interactively and read error messages. When your code does not behave as expected, open DevTools first and read the error message — it tells you the file name and line number.
Lab Safety and Good Habits
There are no electrical or physical hazards in this lab. Professional safety in software work means protecting users from harm:
- Sanitize all user input before displaying it on a page.
- Never commit credentials or API keys to a repository.
- Keep VS Code and browser extensions updated to avoid known vulnerabilities.
- Save your work frequently and use version control even for small projects.
Key terms10
DOM (Document Object Model)A tree-structured, in-memory representation of an HTML document that JavaScript can read and modify to update the page dynamically.
querySelectorA document method that accepts a CSS selector string and returns the first matching element node, or null if none is found.
NodeListAn ordered collection of DOM nodes returned by querySelectorAll; supports forEach but is not a true Array.
textContentA property that gets or sets the plain-text content of an element, making it safe for displaying user-supplied data because HTML tags are not interpreted.
innerHTMLA property that gets or sets the raw HTML markup inside an element; must never be used with user-supplied input because it enables Cross-Site Scripting (XSS) attacks.
addEventListenerA method on any DOM node or window that registers a callback function to be invoked when a named event type occurs on that target.
Event bubblingThe default behavior in which an event fired on an inner element propagates upward through each ancestor node, triggering any matching listeners along the way.
stopPropagationA method on the event object that prevents the event from traveling further through the DOM tree, stopping both bubbling and capturing for subsequent nodes.
XSS (Cross-Site Scripting)A security vulnerability in which an attacker injects malicious scripts into a web page by exploiting code that places user-controlled text into HTML without sanitization.
classListA property of a DOM element that provides add, remove, and toggle methods for managing CSS class names without overwriting the entire class attribute.
In class: DOM explorer lab: students use document.querySelector, getElementById, textContent, innerHTML (with XSS caution explained by instructor), setAttribute, and classList.add/remove to programmatically transform a static HTML page into a state matching a provided screenshot. · Event listener project: students build a to-do list application entirely in vanilla JS — adding items via a form submit event, marking items complete with a click event that toggles a CSS class, and removing items with a button — with no third-party libraries. · Event propagation experiment: students write code that demonstrates bubbling vs. capturing on a nested element structure, document their observations in the lab log, and apply stopPropagation() to solve a provided event-conflict problem.
Materials: VS Code, Live Server, Chrome DevTools Elements and Console panels, MDN DOM reference, MDN EventTarget.addEventListener reference, provided static HTML starter file
Check: To-do list app demo: instructor performs add, complete-toggle, and delete operations; all three features must function without console errors; pass mark all three features working correctly plus lab log entry submitted.
Practice check8
Answer each question, then check it. Nothing is recorded; this is your own practice.
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.