Modern JavaScript and Web Logic
DOM Manipulation
What is the DOM?
When a browser loads an HTML file, it doesn't just read the text. It creates a live, interactive model of the page's structure called the Document Object Model, or DOM. Think of it as a family tree for your webpage. The <html> tag is the great-grandparent, the <body> and <head> tags are its children, and so on, down to every paragraph, image, and button. Each of these items in the tree is called a "node."
JavaScript can access and modify this tree. It can find any node, change its content, alter its style, or even add and remove nodes entirely. This is the core of how modern websites feel dynamic and responsive without needing to reload the page for every little change.
This tree structure is what allows us to navigate and target specific parts of our webpage with precision. Each element is an object that we can interact with through code.
Finding Your Way Around
Before you can change an element, you need to select it. The most versatile tools for this are querySelector() and querySelectorAll(). These methods use CSS selectors—the same syntax you use in your stylesheets—to find elements in the DOM.
querySelector() finds the first element that matches the selector. If it can't find a match, it returns null.
// Imagine this HTML:
// <div id="main">
// <p class="intro">Hello, world!</p>
// </div>
// Select by ID
const mainDiv = document.querySelector('#main');
// Select by class
const introP = document.querySelector('.intro');
// Select by tag name (gets the first <p>)
const firstParagraph = document.querySelector('p');
If you need to grab multiple elements, querySelectorAll() is the tool for the job. It returns a static NodeList containing all elements that match the selector. You can then iterate over this list to work with each element individually.
// Imagine this HTML:
// <ul>
// <li class="item">Apple</li>
// <li class="item">Banana</li>
// <li class="item">Cherry</li>
// </ul>
const listItems = document.querySelectorAll('.item');
// listItems is a NodeList containing the three <li> elements
// We can loop through it
listItems.forEach(item => {
console.log(item.textContent);
});
Changing Page Content
Once you have a reference to an element, changing its content is straightforward. The textContent property lets you modify the plain text inside an element, automatically stripping out any HTML tags.
const heading = document.querySelector('h1');
// Reading the content
console.log(heading.textContent); // "Welcome to My Page"
// Changing the content
heading.textContent = 'A New Welcome!';
// The h1 now displays "A New Welcome!"
For situations where you need to insert HTML, use the innerHTML property. This property parses the string you provide as HTML and inserts it into the element.
const mainDiv = document.querySelector('#main');
// Replace the div's content with new HTML
mainDiv.innerHTML = '<h2>New Section</h2><p>This paragraph was added by JavaScript.</p>';
Be very careful with
innerHTML. If you use it to insert content provided by a user, you could be opening your site to security vulnerabilities like Cross-Site Scripting (XSS) attacks. Always usetextContentunless you specifically need to render HTML from a trusted source.
Styles and Classes
JavaScript can also manipulate CSS. Every element has a style property that gives you access to its inline styles. Note that property names written with a hyphen in CSS (like background-color) are converted to camelCase in JavaScript (like backgroundColor).
const message = document.querySelector('#status-message');
// Change multiple CSS properties
message.style.color = 'blue';
message.style.backgroundColor = '#e0f7fa';
message.style.padding = '10px';
message.style.borderLeft = '5px solid blue';
Modifying inline styles is fine for quick, one-off changes. However, a much cleaner and more powerful approach is to add or remove CSS classes. You can define styles for classes like .error or .hidden in your stylesheet, and then use JavaScript to toggle these classes on your elements.
The classList property provides easy methods for this: add(), remove(), and toggle().
const alertBox = document.querySelector('.alert');
// Add a class to apply error styles
alertBox.classList.add('alert-error');
// Remove a class
alertBox.classList.remove('is-hidden');
// Toggle a class: if it exists, remove it. If not, add it.
const menu = document.querySelector('#mobile-menu');
const menuButton = document.querySelector('#menu-button');
menuButton.addEventListener('click', () => {
menu.classList.toggle('is-open');
});
Creating New Elements
Finally, you can create brand-new elements from scratch and add them to the DOM. This is done in a two-step process: first create the element, then append it to an existing element on the page.
// 1. Create a new element in memory
const newParagraph = document.createElement('p');
// 2. Set its properties
newParagraph.textContent = 'This was created dynamically!';
newParagraph.classList.add('new-content');
// 3. Find a parent element on the page
const container = document.querySelector('.container');
// 4. Append the new element to the parent
container.appendChild(newParagraph);
This pattern is fundamental to building web applications. When a user submits a form, adds an item to a cart, or loads more content, you'll often be creating new elements and appending them to the document to reflect that change.
Ready to test your knowledge? Let's see how well you've grasped these concepts.
What does the Document Object Model (DOM) represent?
Which JavaScript method would you use to select ALL <li> elements inside a <ul> with the id "user-list"?
With these tools, you can transform a static HTML page into a living, breathing application that responds to user input in real time.