×
By the end of this chapter, you should be able to:
Throughout this chapter we'll be using the following HTML as our working example. Feel free to copy and paste this text into your text editor, then open the page in Google Chrome.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <button class="first_button" onclick="firstClick()">Click me first!</button> <button class="second_button" >Click me second!</button> <button class="third_button">Click me third!</button> </body> </html>
From MDN
DOM Events are sent to notify code of interesting things that have taken place. Each event is represented by an object which is based on the Event interface, and may have additional custom fields and/or functions used to get additional information about what happened. Events can represent everything from basic user interactions to automated notifications of things happening in the rendering model.
In a nutshell, events are things we can trigger by interacting with the browser. Here are some potential events we can listen (and then execute some code) for:
You can see a full list here.
There are three ways that we can add event listeners to our code. Given an element we want to listen to, and a function we want to execute, we can either attach the name of the function to the element in HTML, in JavaScript, or we can use the addEventListener
method.
Here's some JavaScript code that highlights each one of these approaches:
// Option 1: - directly in HTML. Note that in your HTML, // the first button makes reference to a function called firstClick // in the onclick attribute function firstClick(){ alert("you clicked the first button!"); } // Option 2 - attach the function to the element let secondButton = document.querySelector('.second_button'); secondButton.onclick = function(){ alert("you clicked the second button!"); } // Option 3 - use addEventListener let thirdButton = document.querySelector('.third_button'); thirdButton.addEventListener("click", function(){ alert("you clicked the third button!"); });
So which one is best?
It is often best to either use the second or third option, as these are a bit more customizable, but it is good to know all of your options. In this course, we will primarily be using addEventListener
.
Let's go back to our initial example, remove the onclick
attribute from our first button, and add some event listeners to our buttons.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <button class="first_button">Click me first!</button> <button class="second_button" >Click me second!</button> <button class="third_button">Click me third!</button> </body> </html>
Just like when changing multiple elements, we need to iterate through each one - we cannot just add an event listener to an array-like object of element nodes.
let buttons = document.getElementsByTagName("button"); // this will NOT work - what kind of error do you get? buttons.addEventListener("click", function(){ alert("You just clicked a button"); }); // we have to add the event listener to each button for(let i=0; i<buttons.length; i++){ buttons[i].addEventListener("click", function(){ alert('You just clicked on a button!'); }); }
Sometimes we want to stop listening for events. To do that we use the removeEventListener
method, but it has some quirks you should be aware of. Assuming you've still got those alert messages being triggered when you click on a button, let's take a look at the following code:
let buttons = document.getElementsByTagName("button"); // this will NOT work buttons.removeEventListener("click", function(){ alert("You just clicked a button"); }); // we have to remove the event listener to each button but this STILL won't work! That is because we are using an annonymous function for(let i=0; i<buttons.length; i++){ buttons[i].removeEventListener("click", function(){ alert('You just clicked on a button!'); }); }
In order to successfully remove an event listener, the callback that we pass in can't be an anonymous function. Let's clear out all the JavaScript and start from scratch. The code below should work; if you run it, event listeners will be added and then removed, so that nothing happens when you click on a button.
// In order to remove, we have to name our function before adding it instead of adding an anonymous function function alertData(){ alert("You just clicked a button"); } for(let i=0; i<buttons.length; i++){ buttons[i].addEventListener("click", alertData); } // since we have named our function, we know which one to remove for(let i=0; i<buttons.length; i++){ buttons[i].removeEventListener("click", alertData); }
Another issue that we may face is when we have code like this:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> let container = document.getElementById("container"); container.innerText = "Hello World"; // This throws an error! </script> </head> <body> <div id="container"> </div> </body> </html>
What's going on here?? Well, since our script
tag is running before the DOM has loaded, it has no idea what the <div id="container"></div>
is! What we can do is wait for the DOM to load before executing any JavaScript. This can be done either with the load
event or the DOMContentLoaded
event. You can read about the difference between them here.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> document.addEventListener("DOMContentLoaded", function(){ let container = document.getElementById("container"); container.innerText = "Hello World"; // This works now! }); </script> </head> <body> <div id="container"> </div> </body> </html>
You should get in the habit of always waiting for the DOM content to load before you try to manipulate anything on the page with JavaScript.
When you're ready, move on to Events Continued