DOM Tips & Tricks. An Entry Level Guide for Developers

Ram BhardwajRam Bhardwaj
5 min read

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(), and autoPlayToggle(). 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

20
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