Understanding Event Listeners : The key to Dynamic Web Pages

Understanding Event Listeners : The key to Dynamic Web Pages

·

6 min read

When you visit a website, you might switch to dark mode. In dark mode, the website's background changes to black or dark colors, and the text turns white. You may have wondered how we can add different functions to the same button. Let's explore event listeners to make our websites more interactive.

Things You should know

Before learning about Event Listeners, you should understand what events are and how we can manage them without using event listeners.

You can read this from https://blogs-himanshu.hashnode.dev/javascript-events-explained-website-reactions-to-user-actions

Event Listeners

When you want to add different functions in one event like when you click a button for switching theme from light to dark mode, background color changes and its text color also changes. This can’t be done using simple event handlers. You must use addEventListeners to add different functionalities.

For instance,

function changeBackground() {
    buttonElement.style.backgroundColor = "black"
}

function changeTextColor() {
    buttonElement.style.color = "white"
}

buttonElement.onclick = changeBackground
buttonElement.onclick = changeTextColor  // replaces the previous handler

In this code, first function is overwritten by second functions. So, when we click the button only text color is changes to white.

To change this, we can use addEventListener.

addEventListener()

addEventListener is a JavaScript property that allows you to add multiple functions to a single event.

Syntax :

element.addEventListener(event, handler, [options]);
  • event : Event name, e.g., click

  • handler : The handler function

  • options : An additional optional object with properties:

    • once: if true, then the listener is automatically removed after it triggers.

    • capture: the phase where to handle the event. For historical reasons, options can also be false/true, that’s the same as {capture: false/true}.

    • passive: if true, then the handler will not call preventDefault()

Lets apply addEventListener to create a button that change the background color and text color.

buttonElement.addEventListener('click', function() {
    if (buttonElement.innerText == "Dark Mode") {
        body.style.backgroundColor = "black"
        body.style.color = "ghostwhite"
        buttonElement.innerText = "Light Mode"
    }
    else {
        body.style.backgroundColor = "ghostwhite"
        body.style.color = "black"
        buttonElement.innerText = "Dark Mode"
    }
})

In this code, when a user clicks the button, if the button is in Light Mode, the background color of the body will change to black and the text color will change to ghostwhite. If the button is in Dark Mode, the background color will change to ghostwhite and the text color will change to black.

removeEventListener()

Just as you added event listeners to elements, you can also remove them using removeEventListener.

Syntax :

element.removeEventListener(event, handler, [options])

But to remove the handler, we have to give the same function we give to addEventListener.

This doesn’t work :

element.addEventListener('click', function() {alert("Hello Viewer")})

element.removeEventListener('click', function() {alert("Hello Viewer")})

After looking at the code, you might wonder why these functions seem the same as those given to addEventListener, but they are not. Each function has a different address in memory when executed.

To correctly remove the handler, follow this method:

function greet() {
    alert("Hello Viewer")
}

element.addEventListener("click", greet)

element.removeEventListener("click", greet)

Please note – if we don’t store the function in a variable, then we can’t remove it. There’s no way to “read back” handlers assigned by addEventListener.

Multiple handlers

We can call addEventListener to add multiple handlers. Just like this:

function handler1() {
    alert('Hello Viewer');
  };

  function handler2() {
    alert('Hello Viewer, again');
  }

  elem.onclick = () => alert("Hello");
  elem.addEventListener("click", handler1); // Hello Viewer
  elem.addEventListener("click", handler2); // Hello Viewer, again

Event Object

To learn more about how events work, such as what happens when a button is clicked or a key is pressed, we need to understand the event object.

An event object is created when an event occurs. The browser generates a new event object, fills it with details, and passes it as an argument to the handler.

Here’s an example of getting pointer coordinates from the event object:

<input type="button" value="Click me" id="elem">

<script>
  elem.onclick = function(event) {
    // show event type, element and coordinates of the click
    alert(event.type + " at " + event.currentTarget);
    alert("Coordinates: " + event.clientX + ":" + event.clientY);
  };
</script>

Some properties of the event object :

  • event.type : Event type, here its “click”.

  • event.currentTarget : Element that handled the event. That’s exactly the same as this, unless the handler is an arrow function, or its this is bound to something else, then we can get the element from event.currentTarget.

  • event.clientX / event.clientY : Window relative coordinates of the cursor, for pointer events

The event object is also available in HTML handlers

If we assign a handler in HTML, we can also use the event object, like this:

<input type="button" onclick="alert(event.type)" value="Event type">

That’s possible because when the browser reads the attribute, it creates a handler like this: function(event) {alert(event.type)}. That is: its first argument is called “event“, and the body is taken from the attribute.

Object handlers: handleEvent

We can assign not only function but as object also to handler in addEventListener. When an event occurs, its handleEvent method is called.

For instance,

let obj = {
    handleEvent(event) {
        alert(event.type + "at" + event.currentTarget)
    }
}

element.addEventListener("click", obj)

As you can see, when addEventListener receives an object as a handler, it call obj.handleEvent(event) in case of an event.

We can use custom classes also, like this:

class Menu {
    handleEvent(event) {
        switch(event) {
            case "keydown" :
                alert("Hello Viewer, I am in keydown")
                break
            case "keyup" :
                alert("Hello Viewer, I am in keyup")
                break
        }
    }
}

let menu = new Menu()

element.addEventListener("keyup", menu)
element.addEventListener("keydown", menu)

Here the same object handles both events. Please note that we need to explicitly setup the events to listen using addEventListener. The menu object only gets mousedown and mouseup here, not any other types of events.

The method handleEvent does not have to do all the job by itself. It can call other event-specific methods instead, like this:

class Menu {
    handleEvent(event) {
      // mousedown -> onMousedown
      let method = 'on' + event.type[0].toUpperCase() + event.type.slice(1);
      this[method](event);
    }

    onKeydown() {
      alert("Hello Viewer, I am in keydown")
    }

    onKeyup() {
      alert("Hello Viewer, I am in keyup")
    }
  }

  let menu = new Menu();
  elem.addEventListener('keydown', menu);
  elem.addEventListener('keyup', menu);

Now event handlers are clearly separated, that may be easier to support.

Conclusion

Event listeners are a powerful tool in JavaScript that enable developers to create dynamic and interactive web pages. By using addEventListener, you can attach multiple functions to a single event, allowing for complex interactions like theme switching with a single button click. Additionally, removeEventListener provides the flexibility to manage these interactions by removing handlers when they are no longer needed. Understanding the event object and how to handle events with both functions and objects further enhances your ability to create responsive and user-friendly web applications. By mastering event listeners, you can significantly improve the interactivity and functionality of your websites, providing a richer experience for users.