What are Events in JavaScript and How to Handle Them?
Tags: javascript, webdev, beginners, programming
Published: 2022-08-10 20:04:00

_Originally published on [my personal blog](https://blog.shahednasser.com/what-are-events-in-javascript-and-how-to-handle-them/)._

Events in JavaScript allow developers to listen for changes in the document and handle them as necessary. For example, you can listen to when a button is clicked to open a modal. Another example is showing the "scroll up" button when the user scrolls halfway through the page.

This article helps beginners understand what Events are in JavaScript and how to handle them.

Why Use Events
--------------

Modern websites have evolved to be interactive and reactive. Instead of presenting information or functionalities all at once, some can be shown to the user based on a specific action performed. The example mentioned earlier in the article illustrates this.

Events are also helpful in detecting different states of your website. For example, detecting when a screen is resized can help to ensure the responsiveness of certain elements on the page.

The list of use cases where events are helpful is endless. Events are an essential part of web development with JavaScript and it's important to understand how to use them.

Add Event Handler
-----------------

To listen to events, you can use the [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener) method. This method is available on every Element and Node in the document.

`addEventListener` accepts three parameters: the first parameter is the name of the event to listen to; the second parameter is the function that handles this event; and the third parameter is an optional parameter that allows you to set more [options for the listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters).

In most cases, you only need to use the first two parameters. Here's an example of handling the `click` event on a button:

```js
const button = document.querySelector("button");
button.addEventListener("click", function (e) {
    alert("Button clicked");
});
```

This retrieves the first button on the page and, when the button is clicked, shows an alert.

![](https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png)

### Can an Event Have More Than One Handler?

The same event can have many handlers. The handlers are triggered one by one when the event occurs.

### Event Object

As you can see, the function passed as a second parameter to `addEventListener` received the argument `e`. This is an [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) object. This object may have different properties depending on its underlying type. However, it has some common important properties.

A frequently used property on the Event object is the `target` property. This is the element that the event was triggered on. This can be helpful when you have the same handler for more than one element.

For example:

```js
document.querySelector("input").addEventListener("change", function (e) {
    alert(e.target.value);
});
```

This code snippet adds an event handler to the first `input` element on the `change` event. The `change` event is triggered when you change the value of the input, then move the focus from the input (for example, click on something else on the page).

When the `change` event occurs and the handler is triggered, the value of the input is retrieved using `e.target.value` and used in an alert.

### Prevent Default Behavior of the Event

In some cases, you want to prevent the default behavior of certain events. For example, when a link is clicked on a page, you might want to show a confirmation message before the user is actually taken to a new page.

To prevent the default behavior of an event, you can use the `preventDefault()` method on the Event object.

For example:

```js
const a = document.querySelector("a.some-link");
a.addEventListener("click", function (e) {
    e.preventDefault();
    if(confirm("Are you sure?")) {
      window.location.href = e.target.href;
    }
});
```

This adds an event handler to the `click` events on a link that has the class `some-link`. In the event handler, `e.preventDefault()` is used to prevent the default behavior of opening the page indicated in the `href` attribute.

It then shows the user a confirmation window, and if the user clicks Yes on the confirmation window, it then opens the page as expected.

### Prevent Other Handlers from Handling this Event

As mentioned earlier, an event can have more than one handler. However, in some cases, you might want to cancel other events from handling this event. For example, if a request is sent to the server on form submission and you don't want other event handlers of form submission to send more requests.

There are two methods that can be used to prevent other handlers from handling the same event: `stopPropagation` and `stopImmediatePropagation`.

`stopPropagation` is used to prevent other event handlers from handling an event during the bubbling phase.

Bubbling is when you have the same event on both child and parent elements. The event will be triggered first on the child element, then "bubbled" to the parent element.

In this case, `stopPropagation` prevents the event from being triggered on the parent element if called in the handler of the child element. However, it does not prevent the event from propagating to other event handlers.

To prevent the event from being handled by subsequent handlers, you can use `stopImmediatePropagation`.

For example:

```js
const button = document.querySelector("button");

button.addEventListener("click", function (e) {
  e.stopImmediatePropagation();
  alert("Hello!");
});

button.addEventListener("click", function (e) {
  alert("Bye!")
})
```

Although the button has two event handlers that listen to the `click` event, only the first one will run since it calls the `stopImmediatePropagation` function.

### Difference Between preventDefault, stopPropagation, and stopImmediatePropagation

`preventDefault` only prevents the default behavior of the event. However, it does not prevent other handlers from handling the event.

`stopPropagation` and `stopImmediatePropagation` only prevent other handlers from handling the event. However, they don't prevent the default behavior of the event.

If you want to prevent both the default behavior and other handlers from handling the event, use `preventDefault` with either `stopPropagation` or `stopImmediatePropagation`.

### Handle Events on Dynamic Elements

Consider the following example:

```js
const buttons = document.querySelectorAll(".btn");

buttons.forEach((btn) => {
  btn.addEventListener("click", function (e) {
    alert("Hello!");
  });
})

//create new button
const button = document.createElement('button');
button.classList.add('btn');
button.textContent = "Bye";
document.body.append(button);
```

In this example, you first retrieve all buttons that have the class `btn`. Then, you loop over these buttons and add an event listener that just shows the alert "Hello" when the button is clicked.

Then, you dynamically create a new button, add the class `btn` to that button, and add it to the `body` of the document.

If you try clicking buttons that were added in the HTML of the document or that were added prior to adding the event listener, the alert will be shown as expected. However, if you click on the new button, no alert will be shown.

This is because the element was not part of the elements retrieved using `querySelectorAll` as it didn't exist at the time.

Although this is a reasonable outcome, in larger websites, you might not be able to attach an event handler every time you create a new element, or you might want to ensure that the event handler is added to all elements, whether originally or dynamically created, similarly.

In that case, instead of adding the event handler directly to each element separately, you can add the event handler to the document's `body` and use `e.target` to check if the element triggered matches a specific condition.

For example, you can transform the previous example to the following:

```js
document.body.addEventListener("click", function (e) {
  if (e.target.classList.contains("btn")) {
    alert("Hello!");
  }
})

//create new button
const button = document.createElement('button');
button.classList.add('btn');
button.textContent = "Bye";
document.body.append(button);
```

You add a handler to the `click` event on the `body`. In the handler, you check if `e.target` has the class `btn` and only perform the necessary action if it does.

Now, when any of the elements that have the class `btn`, whether dynamically or initially created, are clicked, the event handler will run for them.

This approach, however, will run the event listener on every click event on the body. So, it's important to handle it based on the target carefully.

Remove Event Handler
--------------------

In some cases, you might want to remove an event handler for an element. To do that, you can use the `removeEventListener` method. This method is available on every Element and Node in the document.

This method receives the same parameters `addEventListener` receives. It's important to pass the same function that you passed to `addEventListener`. For that reason, people commonly define the function separately, then pass it to `addEventListener` and `removeEventListener`.

For example:

```js
const button = document.querySelector("button");

function handleClick (e) {
  alert("Hello");
}

button.addEventListener("click", handleClick);

//some time later
button.removeEventListener("click", handleClick);
```

Conclusion
----------

This article scratches the surface of Events and helps you understand them better. To learn more about Events in JavaScript, check out the following resources:

1.  [Introduction to Events](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events)
2.  [Event Reference](https://developer.mozilla.org/en-US/docs/Web/Events)