DOM Tips & Tricks. An Entry Level Guide for Developers


In this blog, I will cover the most frequently used DOM manipulation tasks that every developer should know. From selecting elements and modifying content to handling events and dynamically updating styles, these essential techniques will help you build more interactive and responsive web applications.
Let’s dive in and explore the power of JavaScript DOM manipulation with practical examples!
Basic Operations:
1. Toggling Elements
Changing text and styles dynamically (e.g., Light Bulb Toggle).
Switching between dark mode and light mode.
Demo Project
- https://dom-challenges-q7mnulz9i-ram-bhardwajs-projects.vercel.app/challenge-1/index.html
Tips:
- Check the Status → Perform Operation → Change the Status
toggleBtn.addEventListener('click', ()=>{
if( currStatus == 'Turn On'){ // Check the current status
bulb.classList.remove('off') // Operation
toggleBtn.innerText = "Turn Off" // Operation
body.classList.add('dark-mode') // Operation
statusSign.innerText = 'Status On' // Change the Status
}else{
bulb.classList.add('off')
toggleBtn.innerText = "Turn On"
body.classList.remove('dark-mode')
statusSign.innerText = 'Status Off'
}
})
2. Handling User Input
Capturing user input from text fields.
Displaying input dynamically (e.g., Real-time Form Input Display).
Showing placeholder text when input is empty.
Demo Project
- https://dom-challenges-q7mnulz9i-ram-bhardwajs-projects.vercel.app/challenge-3/index.html
Tips
- Instead of ‘change’ event use ‘input’ event which changes the connected state is real time.
nameInput.addEventListener('input', ()=>{
nameDisplay.textContent = nameInput.value
})
3. Adding new items dynamically
Creating an element from JS based on user actions
Deleting items from a list based on user actions
Updating UI when items are added or removed
Demo Link
- https://dom-challenges-q7mnulz9i-ram-bhardwajs-projects.vercel.app/challenge-4/index.html
Tips:
ADDING ELEMENT: CreateElement → Add CSS class
DELETING ELEMENT: referenceItem.remove()
EDITING ELEMENT: Add eventListener to the item like dblclick → store the current test in an element → create a new input → add the new empty input to the current element → handle events such as if user clicks outside the input area or press enter
document.querySelectorAll(".todo-item").forEach(item => {
item.addEventListener("dblclick", function() {
let currentText = this.innerText;
let input = document.createElement("input");
input.type = "text";
input.value = currentText;
this.innerHTML = "";
this.appendChild(input);
input.focus();
//How blur Works Here: When the user doubleclicks a task, an input field appears for editing.
//If the user clicks anywhere outside the input(i.e., the input loses focus), the blur event triggers.
// The function saveEdit() replaces the input field with the updated task text.
input.addEventListener("blur", function() {
saveEdit(item, input.value);
});
input.addEventListener("keypress", function(event) {
if (event.key === "Enter") {
saveEdit(item, input.value);
}
});
});
});
function saveEdit(item, newText) {
item.innerHTML = newText || "Untitled Task";
}
4. Tracking and Updating State
Displaying statistics (e.g., Total tasks, Completed tasks).
Showing a message when no items are present.
Updating counters dynamically.
deleteTask.addEventListener('click', () => {
total--;
.
.
.
//-------------------------------------------------------
if(total == 0) {
taskList.appendChild(emptyTask);
}
}
Medium Level Operations
Working with Images and Media
Displaying images dynamically (e.g., Image Carousel).
Navigating through images using buttons.
Creating an automatic slideshow with a timer.
Using indicators to switch between images.
Demo Project
https://dom-challenges-q7mnulz9i-ram-bhardwajs-projects.vercel.app/challenge-5/index.html
Tips
Note that when we want an element to be active dynamically based on user Interaction we should use a upper scoped variable which can be changed any where in the code. (currInd in this example)
- The images active state is dependent on the currInd, and whenever we change currInd we call updateCarousel function to change the state.
How to connect an image slide to an indicator and handles the changes based on indicator
- Notice while creating the slide the indicator is connected to each slide and the indicator of the particular slide has an event listener that changes the currInd which updates Carsousel
For autoplaying the slides note that we are updating the carousel every time by increasing the index.
Note that in order to prevent currInd to go out of the array length of images we are % ing it by images.length
For checking if the autoplay is still on we are using a flag boolean and clearInterval() to stop autoplay
Whenever you want to keep your code modular, you can break functionalities into separate functions like
updateCarousel()
,createSlides()
, andautoPlayToggle()
. This makes the code easier to read and maintain.Note that we are calling updateCarousel() in the js file. // Check yourself by running the code why.
Note we can also add keyboard functionality in this. I will leave that up to you to add .
// Image data
const images = [
{ url: 'https://plus.unsplash.com/premium_photo-1666863909125-3a01f038e71f?q=80&w=1986&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
caption: 'Beautiful Mountain Landscape', },
{ url: 'https://plus.unsplash.com/premium_photo-1690576837108-3c8343a1fc83?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
caption: 'Ocean Sunset View',},
{url: 'https://images.unsplash.com/photo-1473448912268-2022ce9509d8?q=80&w=2041&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
caption: 'Autumn Forest Path',},
{url: 'https://plus.unsplash.com/premium_photo-1680466057202-4aa3c6329758?q=80&w=2138&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
caption: 'Urban City Skyline',},
];
const carouselTrack = document.getElementById("carouselTrack");
const caption = document.getElementById("caption");
const prevButton = document.getElementById("prevButton");
const nextButton = document.getElementById("nextButton");
const carouselNav = document.getElementById("carouselNav");
const autoPlayButton = document.getElementById("autoPlayButton");
let currInd = 0; let autoPlayInterval = null; let playing = false;
// previous and next Button
prevButton.addEventListener('click', () => {
currInd = currInd === 0 ? images.length - 1 : currInd - 1;
updateCarousel();
});
nextButton.addEventListener('click', () => {
currInd = currInd === images.length - 1 ? 0 : currInd + 1;
updateCarousel();
});
// autoplay functionality
function autoPlayToggle(){
if(!playing){
autoPlayInterval = setInterval(() => {
currInd = (currInd + 1) % images.length;
updateCarousel();
}, 1000);
playing = true;
autoPlayButton.innerText = "Stop Autoplay";
} else {
clearInterval(autoPlayInterval);
playing = false;
autoPlayButton.innerText = "Start Autoplay";
}
}
autoPlayButton.addEventListener('click', autoPlayToggle);
function createSlides(){
console.log('Created slides');
images.forEach((image, ind) => {
let carouselSlide = document.createElement("div");
carouselSlide.classList.add("carousel-slide");
carouselSlide.style.backgroundImage = `url('${image.url}')`;
carouselTrack.appendChild(carouselSlide);
addIndexIndicator(ind);
});
}
function addIndexIndicator(ind) {
console.log('Added indicator on slides');
let carouselIndicator = document.createElement('div');
carouselIndicator.classList.add('carousel-indicator');
carouselIndicator.setAttribute('id', ind);
carouselIndicator.addEventListener('click', () => {
currInd = parseInt(ind);
updateCarousel();
});
carouselNav.appendChild(carouselIndicator);
}
function updateCarousel(){
console.log('Updating carousel');
carouselTrack.style.transform = `translateX(-${currInd * 100}%)`;
caption.textContent = images[currInd].caption;
document.querySelectorAll('.carousel-indicator').forEach(item => {
item.classList.remove('active');
});
let activeIndicator = document.getElementById(currInd.toString());
if (activeIndicator) {
activeIndicator.classList.add('active');
}
}
createSlides();
// calling this initially so that the slids are shown when the user hasn't yet clicked anywhere
updateCarousel();
Thanks for visiting
Subscribe to my newsletter
Read articles from Ram Bhardwaj directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ram Bhardwaj
Ram Bhardwaj
Sharing what I learn everyday