As a full-stack developer, one of the most essential skills is knowing how to manipulate the DOM (Document Object Model) with JavaScript to update pages dynamically.
According to Statista, 34.5% of JavaScript developers utilize it primarily for DOM manipulation. And 78% of sites use JavaScript, averaging over 150 KB per page according to W3Techs.
So mastering dynamic DOM scripting is a must-have ability. This comprehensive 3k+ word guide will make you an expert at changing HTML elements with JavaScript.
The Document Object Model (DOM)
The DOM represents the structured nodes of HTML documents as programmable JavaScript objects. It allows us to write scripts that can:
- Access and modify page elements
- Respond to events
- Develop dynamic UIs
As MDN web docs explain:
"The DOM model represents a document with a logical tree. Each branch of the tree ends in a node, and each node contains objects. DOM methods allow programmatic access to the tree."
When a web browser loads a page, it parses HTML and builds a DOM tree model of objects representing each tag, attribute, and piece of text.

A visualization of the DOM tree (Source: sitepoint)
Here is a basic DOM node object structure:
{
nodeName: ‘H1‘,
nodeValue: ‘Hello World‘,
nodeType: 1,
// Properties
textContent: ‘Hello world‘,
innerHTML: ‘<b>Hello world</b>‘,
// Child nodes
childNodes: [
{/* node */}, {/* node */}
],
// Access parent node
parentNode: {/* node */}
}
As you can see, it contains tons of meta data and properties for accessing other nodes.
By learning DOM manipulation methods, you can traverse this object model and change anything on a web page.
Accessing Elements
The first step to manipulating an element is accessing it from the DOM tree. There are several ways to traverse and find elements, including:
By ID
Gets an element by its unique ID attribute using getElementById().
const title = document.getElementById(‘page-title‘);
By Tag Name
Gets all elements matching a tag name with getElementsByTagName().
const divs = document.getElementsByTagName(‘div‘);
By Class
Returns elements that have a specific class name using getElementsByClassName().
const panels = document.getElementsByClassName(‘panel‘);
By CSS Selector
Query selectors like document.querySelector() and document.querySelectorAll() return references to elements that match the given CSS selector.
For example to find the first paragraph tag:
const para = document.querySelector(‘p‘);
Or get all elements with the class "panel":
const panels = document.querySelectorAll(‘.panel‘);
This uses the same syntax as CSS selectors.
By Relationship
Elements also contain properties that provide access to related nodes:
const parent = element.parentElement;
const children = element.children;
// Get prev/next sibling
const nextSibling = element.nextSibling;
const prevSibling = element.previousSibling;
Once you have a reference to an element, you can manipulate it with properties and methods.
Changing Text Content
A simple DOM change is to modify element text content. This lets you display dynamic text and values in the page.
textContent
The textContent property gets/sets text between the start and end tag of an element:
// Getter
const text = element.textContent;
// Setter
msg.textContent = ‘Hello world!‘;
insertAdjacentText()
You can also insert text at specific positions with insertAdjacentText():
element.insertAdjacentText(‘beforebegin‘, ‘Hello ‘);
The first param is the position: ‘beforebegin‘, ‘afterbegin‘, ‘beforeend‘, or ‘afterend‘.
This method inserts the text node as a sibling to the element.
Example: Live Character Count
Here‘s an example snippet that displays the number of characters entered into a <textarea>, updating the count as you type:
const textarea = document.querySelector(‘textarea‘);
const charCount = document.querySelector(‘.char-count‘);
textarea.addEventListener(‘keyup‘, function(){
// Update counter
charCount.textContent = textarea.value.length;
});
This kind of functionality isn‘t possible with just static HTML.
Changing HTML Content
Along with text, JavaScript allows you to modify the inner HTML structure and tags themselves.
innerHTML
This property gets or sets the raw HTML between an element‘s start and end tag:
// Get HTML
const content = element.innerHTML;
// Set HTML
element.innerHTML = ‘New HTML‘;
Like textContent, this replaces all existing HTML content.
insertAdjacentHTML()
To insert HTML at a specific position:
element.insertAdjacentHTML(‘afterend‘, ‘<div>New element</div>‘);
This inserts the given HTML string relative to the current element‘s position.
Warning: Only modify
innerHTMLwith trusted text. Injecting unsanitized user input can open you up to XSS attacks.
Example: Live Markdown Previewer
Here we have a textarea for entering Markdown, and convert that to HTML inside the preview pane:
const mdInput = document.querySelector(‘#markdown‘);
const preview = document.querySelector(‘#preview‘);
mdInput.addEventListener(‘input‘, function(){
// Convert markdown to HTML
const html = convertMarkdownToHTML(mdInput.value);
// Preview converted HTML
preview.innerHTML = html;
});
This kind of real-time rendering isn‘t possible in static documents.
Changing Attributes
DOM elements also let you manipulate their attributes like id, class, src, etc. Here are some ways to modify attributes:
Direct Assignment
Many common attributes can simply be assigned a new value:
const link = document.querySelector(‘a‘);
// Change href
link.href = ‘http://www.example.com‘;
// Toggle class
link.className = ‘highlight‘;
setAttribute() and getAttribute()
You can get and set any attribute with these methods:
// Get attribute
const className = el.getAttribute(‘class‘);
// Set attribute
el.setAttribute(‘class‘, ‘highlight‘);
hasAttribute() and removeAttribute()
Check if an attribute exists, or remove it:
if(el.hasAttribute(‘disabled‘)){
// Remove attribute
el.removeAttribute(‘disabled‘);
}
dataset
With custom data-* attributes, you can store additional data on elements:
<div id="user" data-id="100" data-role="admin">
<!-- ... -->
</div>
Access that data through the dataset property:
const userid = user.dataset.id; // "100"
const role = user.dataset.role; // "admin"
Example: Toggling an Active State
Here we add/remove a data-active attribute on click:
button.addEventListener(‘click‘, function(e){
if(button.dataset.active == ‘on‘) {
button.removeAttribute(‘data-active‘);
} else {
e.target.setAttribute(‘data-active‘, ‘on‘);
}
});
This kind of state can be useful for styling purposes.
Changing CSS Styles
Of course, being able to modify CSS styles is important for DOM manipulation. There are several approaches:
style Property
The style property lets you access and assign individual CSS rule values:
div.style.color = ‘blue‘;
div.style.marginTop = ‘2em‘;
className & classList
These properties allow managing CSS classes on an element:
// Replace all classes
div.className = ‘blue-text‘;
// Toggle class
div.classList.toggle(‘visible‘);
// Add/remove class
div.classList.add(‘highlight‘);
div.classList.remove(‘highlight‘);
CSSStyleSheet
To make broad style changes across elements, use CSSStyleSheet to modify CSS rules:
// Get stylesheet
const style = document.styleSheets[0];
style.insertRule(‘body { background: black; }‘, 0);
style.deleteRule(0); // Remove first rule
Example: Random Color Highlighter
Clicking this button applies a random background color style to highlight the text:
highlightBtn.addEventListener(‘click‘, function() {
const color = getRandomColor();
// Set style directly
para.style.backgroundColor = color;
para.style.color = "#fff";
});
function getRandomColor() {
return ‘#‘ + Math.floor(Math.random()*16777215).toString(16);
}
This kind of dynamic styling isn‘t possible in plain HTML/CSS.
Modifying The Entire Element
In addition to updating text, attributes, and styles – JavaScript allows replacing and modifying whole elements.
outerHTML
This property lets you get or set the full HTML content including the element tags:
const html = element.outerHTML;
el.outerHTML = ‘<div>This replaced the element</div>‘;
insertAdjacentElement()
Insert a new node relative to the current one:
const newNode = document.createElement(‘div‘);
element.insertAdjacentElement(‘beforebegin‘, newNode);
The position param can be ‘beforebegin‘, ‘afterbegin‘, ‘beforeend‘, or ‘afterend‘.
replaceWith()
Substitutes an element with new content:
const newEl = document.createElement(‘div‘);
element.replaceWith(newEl);
replaceChild()
Swaps out one child node for another:
const newChild = document.createElement(‘p‘);
const parent = document.getElementById(‘parent‘);
parent.replaceChild(newChild, parent.childNodes[0]);
This replaces the first child element of #parent.
Example: Tabbed Widget Interface
This example has a tabbed widget with content that changes dynamically based on user clicks:
tabList.addEventListener(‘click‘, e => {
const tabTarget = e.target; // Clicked tab
// Find & remove current active tab
let currentTab = tabList.querySelector(‘.active‘);
currentTab.classList.remove(‘active‘);
// Add active state on clicked tab
tabTarget.classList.add(‘active‘);
// Hide current tab content
currentContent.style.display = ‘none‘;
// Show target tab content
const tabData = tabTarget.getAttribute(‘data-tab-target‘);
tabContent = document.querySelector(tabData);
tabContent.style.display = ‘‘;
});
This kind of interactivity isn‘t possible using plain HTML/CSS.
Why Learn DOM Manipulation?
Being able to change HTML elements dynamically:
- Allows creating robust UIs and features
- Enables responding to user input
- Unlocks animations/transitions that aren‘t possible in static pages
- Is an essential skill for front-end/full-stack developers
Here are some examples of what‘s possible by combining JavaScript DOM manipulation with HTML and CSS:
- Autocompleting search boxes
- Interactive maps with popup infowindows
- Drag and drop interfaces for moving elements
- Text editors with custom formatting
- Updating charts/graphs with new data
- Modals and slide out menus
- Reordering table rows
- Playing video and audio
- Zooming images
- Parallax scrolling effects
- And essentially any kind of dynamic UI!
Learning DOM scripting opens up endless possibilities for crafting compelling web user experiences.
Many frameworks like React and Vue also utilize DOM manipulation internally to render and update their interfaces. So it‘s an essential ability for any front-end developer.
Key Takeaways
Let‘s summarize the key things we learned about changing HTML elements with JavaScript:
- The DOM is structured as a tree of objects representing each tag/element
- You can traverse this structure to access any node
- Inner text, HTML, attributes, and styles can be modified
- Elements themselves can be added, removed, or replaced
- This enables building highly interactive interfaces
- DOM skills are essential for front-end engineers
I hope this guide gave you a comprehensive overview of dynamically scripting HTML documents! Let me know if you have any other questions.


