23.5. Event Listeners

Using inline event handling is a good way to get started handling events. A second way to handle events uses the DOM objects and methods. Remember, the DOM is an object representation of the entire web page. The DOM allows us to use JavaScript to configure our event handlers. The event handling declaration will no longer be in the HTML element attribute, but will instead be inside <script> tags or in an external JavaScript file.

23.5.1. Add Event Handlers in JavaScript

Before we add event handlers in JavaScript, we need to learn a new vocabulary term related to events in programming. A listener is another name for an event handler. The term listener refers to the code listening for the event to occur. If the code hears the event, then the event is handled.

addEventListener is used to add an event handler, aka listener. addEventListener is a method available on instances of Window, Document, and Element classes.

anElement.addEventListener("eventName", aFunction);

anElement is a reference to a DOM element object. "eventName" is the name of an event that the variable anElement supports. aFunction is a reference to a function. To start, we are going to use a named function.

Example

We want to set the named function youRang as the click handler for the button element. Notice that the value passed in as the event name is "click" instead of "onclick".

 1<!DOCTYPE html>
 2<html>
 3<head>
 4   <title>Use addEventListener</title>
 5</head>
 6<body>
 7   <p id="main-text" class="orange" style="font-weight: bold;">
 8      a bunch of really valuable text...
 9   </p>
10   <button id="ring-button">Ring Bell</button>
11   <script>
12      function youRang() {
13         document.getElementById("main-text").innerHTML += "you rang...";
14         console.log("you rang...");
15      }
16      // Obtain a reference to the button element
17      let button = document.getElementById("ring-button");
18      // Set named function youRang as the click event handler
19      button.addEventListener("click", youRang);
20   </script>
21</body>
22</html>

Result (if button is clicked)

affect on page: adds "you rang..." to <p>
output in console: you rang...

Warning

Be sure to use the correct event name when declaring the event name. An error will NOT be thrown if an invalid event name is given.

Note

This chapter uses DOM methods to add event handlers. When searching online, you may find examples using jQuery to add event handlers, which look like .on("click", ...) or .click(...). jQuery is a JavaScript library designed to simplify working with the DOM. jQuery's popularity has declined as the DOM itself has gained features and improved usablity.

The second parameter of addEventListener is a function. Remember there are many ways to declare a function in JavaScript. So far, we have passed in named functions as the event handler. addEventListener will accept any valid function as the event handler. It's possible, and quite common, to pass in an anonymous function as the event handler.

1anElement.addEventListener("eventName", function() {
2   // function body of anonymous function
3   // this function will be executed when the event is triggered
4});

23.5.2. Event Details

A benefit of using addEventListener is that an event parameter can be passed to the event handler function. This event is an object instance of the Event class, which defines methods and properties related to events.

1anElement.addEventListener("eventName", function(event) {
2   console.log("event type", event.type);
3   console.log("event target", event.target);
4});

event.type is a string name of the event.

event.target is an element object that was the target of the event.

Try It!

Above, we saw how we could use addEventListener to add the function youRang() as the event handler for the Ring Bell button.

Using addEventListener, could you add the function greetFriends() as the event handler for the Greet Friends button?

Try it at repl.it

23.5.3. Event Bubbling

Remember that the DOM is a tree of elements with an <html> element at the root. The tree structure of an html page is made of elements inside of elements. That layering effect can cause some events, like click, to be triggered on a series of elements. Bubbling refers to an event being propagated to ancestor elements, when an event is triggered on an element that has parent elements. Events are triggered first on the element that is most closely affected by the event.

Example

We can add a click handler to a <button>, a <div>, and the <html> element via the document global variable.

 1<!DOCTYPE html>
 2<html>
 3<head>
 4   <title>Event Bubbling</title>
 5   <style>
 6      #toolbar {
 7          padding: 20px;
 8          border: 1px solid black;
 9          background-color:darkcyan;
10      }
11  </style>
12</head>
13<body>
14   <div id="toolbar">
15      <button id="ring-button">Ring Bell</button>
16   </div>
17   <script>
18      let button = document.getElementById("ring-button");
19      button.addEventListener("click", function (event) {
20          console.log("button clicked");
21      });
22      document.getElementById("toolbar").addEventListener("click", function (event) {
23          console.log("toolbar clicked");
24      });
25      document.addEventListener("click", function (event) {
26          console.log("document clicked");
27      });
28   </script>
29</body>
30</html>

Console Output (if button is clicked)

button clicked
toolbar clicked
document clicked

In some cases, you may want to stop events from bubbling up. We can use event.stopPropagation() to stop events from being sent to ancestor elements. Handlers for parent elements will not be triggered if a child element calls event.stopPropagation().

1button.addEventListener("click", function (event) {
2   console.log("button clicked");
3   event.stopPropagation();
4});

Try It!

With the HTML above, what happens when you click in the green?

After you see the result, try adding stopPropagation() to the button click handler and seeing what happens when you click the button.

Try it at repl.it

23.5.4. Check Your Understanding

Question

Do these code snippets have the same effect? button.addEventListener("click", youRang) and <button onclick="youRang();">

Question

Can click events be prevented from bubbling up to ancestor element(s)?

Question

What is passed as the argument to the event handler function?