JavaScript DOM Events - The Beginners Guide To Javascript(Part 8)
Tags: javascript, beginners, tutorial, programming
Published: 2023-05-02 17:44:12

## 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:

```html
<button id="myButton">Click me!</button>
```

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

```javascript
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
  alert('Button clicked!');
});
```

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!

```javascript
button.addEventListener('click', function(event) {
  console.log(event);
});
```

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:

```javascript
button.addEventListener('click', function(event) {
  console.log(event.target);
});
```

## 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:

```html
<button id="myButton">Click me!</button>
<div id="container"></div>
```

```javascript
const container = document.getElementById('container');

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

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:

```html
<div id="outer">
  <div id="inner">Click me!</div>
</div>
```

```javascript
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!');
});
```

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

```
Inner clicked!
Outer clicked!
```

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:

```html
<ul id="itemList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
```

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

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

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

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:

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

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

button.addEventListener('click', handleClick);
```

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:

```javascript
inner.addEventListener('click', function(event) {
  console.log('Inner clicked!');
  event.stopPropagation();
});
```

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`:

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

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

```html
<div id="eventSource">Click me to start the party!</div>
```

```javascript
const eventSource = document.getElementById('eventSource');

eventSource.addEventListener('click', function() {
  eventSource.dispatchEvent(partyStartedEvent);
});
```

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

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

### 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:

```javascript
function debounce(func, wait) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), wait);
  };
}
```

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

```html
<input id="search" type="text" placeholder="Search..." />
```

```javascript
const searchInput = document.getElementById('search');

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

#### 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:

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

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

```javascript
window.addEventListener(
  'scroll',
  throttle(function() {
    console.log('Scrolled:', window.scrollY);
  }, 200)
);
```

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! 🎉