Events

Introduction to Events

In the previous topic we learned how we can manipulate the DOM. So in this topic we will learn how we can make that happen dynamically. The way we do it is using events. Events are actions that occur on our web page. For example a mouse-click or a keypress are events and we can use JavaScript to make our web page to listen and react to those events.

There are three primary ways to handle the events:

  1. Attach functions attributes directly on the HTML elements
  2. Set the on_event_ property on the DOM object in our JavaScript
  3. Attach event listeners to the nodes in our JavaScript

The third way with the event listeners is definitely the preferred method. However we will regularly see the others in use, so we’re going to cover all three.

Learning Objectives

  • How "events" and "listeners" work.
  • The three ways to use events in our code
  • How "bubbling" works.

Basic Example

Now we are going to see a basic example using all three methods. So we are going to create 3 buttons that all alert "BUTTON" when clicked.

You can try them all out using your own HTML file, or using something like CodePen.

Method 1 (Not recommended)

<button onclick="alert('BUTTON')">Click Me</button>

This way is less than ideal because we are cluttering our HTML with JavaScript. In addition, we can only have 1 "onclick" event per element.

Method 2 (Not recommended)

<!-- HTML FILE -->
<button id="btn">Click Me</button>
// JAVASCRIPT FILE
const btn = document.querySelector('#btn');
btn.onclick = () => alert("BUTTON");

*If you need further assistance with the arrow functions check this link: Arrow Functions Basics.

This way is a little better since we have moved the JS out of the HTML and into a JS file. However we still have the problem that a DOM element can only have 1 "onclick" property.

Method 3 (Recommended)

<!-- HTML FILE -->
<button id="btn">Click Me Too</button>
// JAVASCRIPT FILE
const btn = document.querySelector('#btn');
btn.addEventListener('click', () => {
  alert("BUTTON");
});

This way is much better since we have our HTML and JavaScript separated and we also allow multiple event listeners if the need arises. Although it is a bit more complex to set up, it is more flexible.

We can also use these methods with named functions if we want to.

<!-- HTML FILE -->
<!-- METHOD 1 -->
<button id="btn" onclick="alertFunction()">CLICK ME AGAIN</button>
// JAVASCRIPT FILE
const btn = document.querySelector('#btn');
function alertFunction() {
  alert("BUTTON");
}
// METHOD 2
btn.onclick = alertFunction;
// METHOD 3
btn.addEventListener('click', alertFunction);

It is a really good idea to name the functions. The code is cleaner and it is really handy if you are going to use it in multiple places.

If we want we can access more information about the events. We can do that by passing a parameter to the function we are calling. Let’s see how we can do it.

// JAVASCRIPT FILE
btn.addEventListener('click', function (e) {
  console.log(e);
});

*Note that function (e) is a callback from addEventListener. If you need further assistance with callbacks you can check this link Callbacks.

The e in that function is an object that references the event itself. Within that object you have access to many useful properties and functions such as which mouse button or key was pressed, or information about the event’s target. The target refers to the DOM node that was clicked.

So we can access the button by accessing the target property as:

// JAVASCRIPT FILE
btn.addEventListener('click', function (e) {
  console.log(e.target);
});

and then we can change the background color of the button as:

// JAVASCRIPT FILE
btn.addEventListener('click', function (e) {
  e.target.style.background = 'purple';
});

Attaching listeners to groups of nodes

In case we want to attach similar event listeners to many elements there is a way to make our code more efficient rather than writing the same code over and over again.

In previous topics we learned that we can get a nodelist of all the items matching a specific selector. We can do that with the querySelectorAll('selector'). So in order to add a listener to all of them all we have to do is to iterate through the entire list.

<!-- HTML FILE -->
<div id="wrapper">
    <button id="1">Click Me</button>
    <button id="2">Click Me</button>
    <button id="3">Click Me</button>
</div>
// JAVASCRIPT FILE
// buttons is a node list. It looks and acts much like an array.
const btns = document.querySelectorAll('button');
// we use the .forEach method to iterate through each button
btns.forEach((btn) => {
  // and for each one we add a 'click' listener
  btn.addEventListener('click', () => {
    alert(btn.id);
  });
});

What we have learned so far in regards to DOM manipulation and event handling is just the tip of the iceberg. However you have learned enough so as to complete some exercises.

In our previous examples we have used the click event but there are a lot more available to you!

Below is a list of some useful events:

  • click
  • dblclick
  • keypress
  • keydown
  • keyup

In this page HTML DOM Events you will find a more complete list of events as well as an explanation of each one.

Avoiding Confusion

As you’ve seen, you can define an event handler in 3 different ways.

  1. Using the addEventListener method (Recommended)
document.querySelector(".box").addEventListener( "click", function( event ){ ... });
document.querySelector("form").addEventListener( "submit", function( event ){ ... });
document.body.addEventListener( "keyup", function( event ){ ... });
  1. Using the on<EVENTNAME> property syntax (Not recommended)
document.querySelector(".box").onclick = function( event ){ ... };
document.querySelector("form").onsubmit = function( event ){ ... };
document.body.addEventListener.onkeyup = function( event ){ ... };
  1. Using an attribute with the on<EVENTNAME> directly in an HTML element (Not recommended):
<div class="box" onclick="clickHandler()">Click me</div>
<form onsubmit="submit()">
    <!-- CONTENT -->
</form>
<body onkeyup="handleKey()">

Events in the first syntax are used like this (nouns): ‘click’, ‘submit’, ‘change’, ‘scroll’, etc.

While using the 2nd syntax, are prefixed with the ‘on’ keyword: ‘onclick’, ‘onsubmit’, ‘onchange’, ‘onscroll’, etc.

The second syntax corresponds to element properties and should not be confused with the event names used in the first case.

Additional Resources

In this section you can find a lot of helpful links to other content. This is a supplemental material for you if you want to dive deeper into some concepts.