Set up a small browser example
The Document Object Model, or DOM, represents a web page as objects that JavaScript can inspect and change. The examples here run in a modern browser’s developer console on a page where you can modify the document. Paste the following JavaScript into the console first. It creates a notice with a message and a button, so you do not need a separate HTML file.
const panel = document.createElement("section"); panel.className = "notice"; const message = document.createElement("p"); message.className = "notice-message"; message.textContent = "Waiting for an update."; const button = document.createElement("button"); button.type = "button"; button.textContent = "Show update"; panel.append(message, button); document.body.append(panel);
The notice appears at the end of the page. Its class names give us useful selectors, while the button provides an action we can respond to. If you run the setup twice, you will create two notices; reload the page before repeating the exercise.
Find the element you mean to change
document.querySelector accepts a CSS selector and returns the first matching element, or null if nothing matches. For this example, document.querySelector(".notice .notice-message") finds a message inside a notice. The space in that selector means “somewhere inside”; the two periods mark class names. document.querySelector(".notice button") finds the first button inside a notice.
Try entering those expressions in the console to inspect the returned elements. A selector should describe the intended target closely enough that another element on the page is unlikely to match first. If several elements do match, querySelector does not return all of them; use querySelectorAll when you need a collection. If you already have a reference to a container, you can also call panel.querySelector(".notice-message") to limit the search to that container.
Always account for a missing result before calling a method or setting a property on it. Selectors can stop matching after a page’s structure changes. An invalid CSS selector can also throw an error, so check selectors you construct rather than assuming every string is valid.
Update plain text with textContent
The textContent property reads or replaces an element’s text. Setting message.textContent = "Update complete." changes the paragraph in the example. It treats the assigned value as text, not as HTML markup. That makes it a suitable choice for ordinary labels and messages, including text supplied by a user that should be displayed rather than interpreted as markup.
Replacing textContent also replaces the element’s existing child content. If a container holds links, icons, or other elements you need to keep, select a dedicated text element inside it instead of assigning textContent to the whole container. In this example the paragraph exists solely to hold the status message, so replacing its contents is straightforward.
textContent changes what the page says; it does not describe a visual state on its own. For that, a CSS class can provide a separate hook. Keeping the message and the styling hook distinct makes each change easier to understand.
Use classList to represent state
An element’s classList offers methods such as add, remove, contains, and toggle. Unlike assigning a new value to className, these methods can change one class without discarding the others. The two-argument form of toggle is especially useful: classList.toggle("is-updated", true) adds the class, while passing false removes it.
Paste the following code after the setup. It selects the notice’s message and button, then changes the message, button label, and state class whenever the button is clicked.
const selectedMessage = panel.querySelector(".notice-message"); const selectedButton = panel.querySelector("button"); if (selectedMessage && selectedButton) { let updated = false; selectedButton.addEventListener("click", () => { updated = !updated; selectedMessage.textContent = updated ? "Update complete." : "Waiting for an update."; selectedMessage.classList.toggle("is-updated", updated); selectedButton.textContent = updated ? "Reset" : "Show update"; }); }
Click the button and inspect the paragraph in the developer tools to see the class appear and disappear. The class alone does not change the appearance: a page would also need a CSS rule targeting .is-updated to give that state a visible style. The changing button label tells users what clicking it will do next, even without that styling.
Keep selection and updates predictable
This example keeps references to the elements it updates, so it does not need to search the document on every click. If another part of your code removes and replaces those elements, the saved references will still point to the old objects. In that situation, select the new elements or arrange the code so one component owns its updates.
For larger interfaces, decide which element owns each piece of text and which classes represent its states. Use querySelector to obtain a specific element, textContent to set its plain text, and classList to adjust a state class without overwriting unrelated classes. Together, these small APIs cover many everyday DOM updates while leaving the page’s structure intact.



