DEV Community

Cover image for JavaScript DOM Events - The Beginners Guide To Javascript(Part 8)
Cameron Lucas
Cameron Lucas

Posted on • Edited on

JavaScript DOM Events - The Beginners Guide To Javascript(Part 8)

Let's Get the Party Started with JavaScript DOM Events! 🎉

Hey there, fellow JavaScript aficionados! Today, we're going to dive into the world of DOM events. If you've ever wanted to make your web pages come to life and respond to user interactions, then this is the blog post for you! By the end of this article, you'll be able to:

  • Add event listeners for events such as click
  • Explore the event object
  • Explain event bubbling
  • Use event bubbling to implement event delegation
  • Stop an event from bubbling

So, let's get this party started! 🥳

What are DOM events?

DOM events are actions or occurrences that happen in the browser, like a button being clicked, a page finishing loading, or an element being updated. JavaScript allows us to listen for these events and react to them with code!

What's an Event Listener?

Event listeners are like the DJ at our JavaScript party. They listen for specific events and then perform a function (aka, play a sick beat) when the event occurs. With event listeners, we can make our web pages interactive and responsive to user actions.

Our first Event Listener

Let's start by creating a simple button and adding a click event listener to it. Here's the HTML:

<button id="myButton">Click me!</button>
Enter fullscreen mode Exit fullscreen mode

Now, let's add a click event listener using JavaScript:

const button = document.getElementById('myButton');
button.addEventListener('click', function() {
  alert('Button clicked!');
});
Enter fullscreen mode Exit fullscreen mode

When you click the button, you'll see an alert saying "Button clicked!" Neat, right? 🎉

The Event Object

When an event occurs, the event listener function receives an event object containing information about the event. Let's take a look at this object!

button.addEventListener('click', function(event) {
  console.log(event);
});
Enter fullscreen mode Exit fullscreen mode

Click the button, and you'll see the event object logged to the console. There's a ton of info in there! For now, let's focus on the target property, which refers to the element that triggered the event:

button.addEventListener('click', function(event) {
  console.log(event.target);
});
Enter fullscreen mode Exit fullscreen mode

Adding New Elements To The DOM

Now that we know how to add event listeners, let's see how we can use them to add new elements to the DOM. Let's create a new <p> element every time the button is clicked:

<button id="myButton">Click me!</button>
<div id="container"></div>
Enter fullscreen mode Exit fullscreen mode
const container = document.getElementById('container');

button.addEventListener('click', function() {
  const newParagraph = document.createElement('p');
  newParagraph.textContent = 'You clicked the button!';
  container.appendChild(newParagraph);
});
Enter fullscreen mode Exit fullscreen mode

Now, every time the button is clicked, a new paragraph appears! ✨

Event Bubbling

In the world of DOM events, event bubbling is like a party game of "telephone." When an event occurs on an element, it first triggers any event listeners on that element, then moves up to the element's parent and triggers any event listeners there, and so on, all the way up to the window object. This is called event bubbling.

Let's see this in action:

<div id="outer">
  <div id="inner">Click me!</div>
</div>
Enter fullscreen mode Exit fullscreen mode
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');

outer.addEventListener('click', function() {
  console.log('Outer clicked!');
});

inner.addEventListener('click', function() {
  console.log('Inner clicked!');
});
Enter fullscreen mode Exit fullscreen mode

When you click the inner <div>, you'll see the following output in the console:

Inner clicked!
Outer clicked!
Enter fullscreen mode Exit fullscreen mode

The click event bubbled up from the inner <div> to the outer <div>!

Event Delegation

Event delegation is like having a party organizer who's in charge of delegating tasks to others. Instead of assigning event listeners to individual elements, we can take advantage of event bubbling and delegate the event handling to a single parent element. This can be especially useful when working with dynamic content or large lists.

Let's see an example. Imagine we have a list of items, and we want to log the item's text when clicked:

<ul id="itemList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Using event delegation, we'll add an event listener to the <ul> element:

const itemList = document.getElementById('itemList');

itemList.addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    console.log(event.target.textContent);
  }
});
Enter fullscreen mode Exit fullscreen mode

Now, when you click on any of the <li> elements, their text content will be logged to the console. 🎉

Removing Event Listeners

Sometimes, like when the party is over, you might want to remove an event listener. To do that, you need to use the removeEventListener method. However, there's a catch: you must pass the same function reference to removeEventListener as the one you used with addEventListener.

Let's update our button example to remove the event listener after the button has been clicked:

const button = document.getElementById('myButton');

function handleClick() {
  alert('Button clicked!');
  button.removeEventListener('click', handleClick);
}

button.addEventListener('click', handleClick);
Enter fullscreen mode Exit fullscreen mode

Now, the button will only trigger the alert once!

Stopping Event Bubbling

Sometimes, you might not want an event to bubble up. To stop event bubbling, you can use the stopPropagation method of the event object:

inner.addEventListener('click', function(event) {
  console.log('Inner clicked!');
  event.stopPropagation();
});
Enter fullscreen mode Exit fullscreen mode

Now, when you click the inner <div>, you'll only see "Inner clicked!" in the console, and the event won't bubble up to the outer <div>.

Bonus Material

There is a lot more to learn about DOM Events and how to use them in JavaScript. Here are a few additional topics you might want to explore:

Custom Events

Sometimes, you might want to create your own custom events to communicate between different parts of your application. Custom events allow you to trigger and listen for events that are specific to your app's needs.

Let's create a custom event called partyStarted:

const partyStartedEvent = new CustomEvent('partyStarted', {
  detail: {
    message: "Let's get this party started!",
  },
});
Enter fullscreen mode Exit fullscreen mode

Now, let's dispatch our custom event using the dispatchEvent method on an element:

<div id="eventSource">Click me to start the party!</div>
Enter fullscreen mode Exit fullscreen mode
const eventSource = document.getElementById('eventSource');

eventSource.addEventListener('click', function() {
  eventSource.dispatchEvent(partyStartedEvent);
});
Enter fullscreen mode Exit fullscreen mode

Finally, let's listen for our custom partyStarted event and do something when it's triggered:

eventSource.addEventListener('partyStarted', function(event) {
  console.log(event.detail.message); // Output: "Let's get this party started!"
});
Enter fullscreen mode Exit fullscreen mode

Debouncing and Throttling

When dealing with events that can be triggered rapidly (e.g., scrolling, resizing, or typing), it's important to optimize performance by limiting the number of times your event listener function is executed. This can be achieved with debouncing and throttling.

Debouncing

Debouncing delays the execution of the event listener function until a specified time has passed without the event being triggered again. In other words, the function will only be executed once after the last event occurrence.

Here's a simple debounce function:

function debounce(func, wait) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), wait);
  };
}
Enter fullscreen mode Exit fullscreen mode

Now, let's debounce an event listener for the input event:

<input id="search" type="text" placeholder="Search..." />
Enter fullscreen mode Exit fullscreen mode
const searchInput = document.getElementById('search');

searchInput.addEventListener(
  'input',
  debounce(function() {
    console.log('Input changed:', searchInput.value);
  }, 250)
);
Enter fullscreen mode Exit fullscreen mode

Throttling

Throttling, on the other hand, limits the execution of the event listener function to a specified rate. The function will be executed at most once every given time interval.

Here's a simple throttle function:

function throttle(func, limit) {
  let lastCall = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastCall > limit) {
      lastCall = now;
      func.apply(this, args);
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

Let's throttle an event listener for the scroll event:

window.addEventListener(
  'scroll',
  throttle(function() {
    console.log('Scrolled:', window.scrollY);
  }, 200)
);
Enter fullscreen mode Exit fullscreen mode

Now, your event listeners will only be executed at the specified rate, improving the performance of your app!

And there you have it, folks! We've covered DOM events, event listeners, event bubbling, event delegation, removing event listeners, custom events, and more.

You're now ready to make your web pages more interactive and fun! Keep on coding, and see you at the next JavaScript party! 🎉

Top comments (0)