Take a look at the following example. Run the CodePen demo and click the button that says "Click me". An alert box should pop up.
Open demo in new tabSo what exactly is happening here? Here is the code that achieved this behavior:
1<button onclick="success()">Click me</button>
The onclick
attribute inside the <button>
element is called an event handler. When the <button>
receives the "click" event, it will execute the success()
function, which is defined in the JavaScript file.
1function success() {
2 alert("Success!");
3}
When the success()
function is executed, it will call the built-in function alert()
, which tells your browser to create an alert box with the specified content.
What is an event
So what exactly is an event?
An event is a user input, a signal from the user to the DOM node. This signal could be a click, a pointer hover, a scroll action, and so on. We will discuss more about the different types of events in the next lesson.
Using JavaScript, you can catch this event signal and create corresponding feedback. For example, in our previous demo, the event is a mouse click on the <button>
element, and the feedback is the alert box that pops up after the button has been clicked.
This is also why JavaScript was created in the first place, to add interactivity to the static web pages, making sure that the user actions are answered in time.
Add an event handler
To begin with, let's talk about how to catch an event using an event handler.
There are two different ways to create an event handler. You can either do it programmatically using JavaScript, or use the corresponding HTML attribute.
The JavaScript way
JavaScript allows you to add an event handler for a selected element using the addEventListener()
function. For example,
1<body>
2 <button id="button">Click me</button>
3
4 <script src="index.js"></script>
5</body>
1let button = document.getElementById("button");
2
3function clicked() {
4 alert("Button clicked.");
5}
6
7button.addEventListener("click", clicked);
Remember that we mentioned before in the asynchronous programming lesson that event handlers are asynchronous functions that accept a callback.
It works similarly to setTimeOut()
, except instead of waiting for the specified time, addEventListener()
waits for the specified event.
And also notice that the function clicked()
is passed to the addEventListener()
function as a parameter. It is not supposed to be executed immediately, which is the whole point of asynchronous programming, so the parentheses are not included.
With addEventListener()
, you are also allowed to add multiple event handlers to the same element.
1let button = document.getElementById("button");
2
3function clicked() {
4 alert("Button clicked.");
5}
6
7function wheel() {
8 alert("Mouse wheel moved.");
9}
10
11button.addEventListener("click", clicked);
12button.addEventListener("wheel", wheel);
If you need to remove an event handler, use the removeEventListener()
function.
1button.removeEventListener("click", clicked);
Using HTML attributes
Besides the addEventListener()
function, you can also use the corresponding HTML attributes. They can be treated as shortcuts for the addEventListener()
function. These attributes are named with the prefix on
, followed by the event name. For example,
1<button id="button" onwheel="wheel()" onclick="clicked()">Click me</button>
This is the same as setting event handlers like this:
1button.addEventListener("click", clicked);
2button.addEventListener("wheel", wheel);
However, this will lead to the problem of mixing your HTML with JavaScript code.
This example is rather simple, but imagine you have more event handlers, and each of them takes a callback function that requires several input arguments. This will make maintaining your application very difficult.
In general, the HTML attributes are better suited for simple event handling, whereas the addEventListener()
is more commonly used in complex scenarios where extra flexibility is needed.
Event propagation
For most event types, the event that fires on the child will propagate to the parent. For example, here we have a <button>
inside a <p>
inside a <div>
:
1<div id="div">
2 <p id="p">
3 <button id="button">Click me</button>
4 </p>
5</div>
You can set up an event handler on the <div>
element.
1let div = document.getElementById("div");
2
3function clicked() {
4 alert("Clicked.");
5}
6
7div.addEventListener("click", clicked);
Notice that when you click on the button, that "click"
event will propagate to the <div>
element, and then be picked up by the event handler.
The event always propagate from the child to the parent. If you have event handlers set up on both the child and the parent, the event will be registered in that order. In our example, the "click"
event will propagate in the following sequence:
1button --> p --> div
For example, let's set up event handlers for <p>
and <button>
as well.
1let div = document.getElementById("div");
2let p = document.getElementById("p");
3let button = document.getElementById("button");
4
5div.addEventListener("click", () => {
6 alert("The <div> element is clicked.");
7});
8
9p.addEventListener("click", () => {
10 alert("The <p> element is clicked.");
11});
12
13button.addEventListener("click", () => {
14 alert("The <button> element is clicked.");
15});
The event object
When addEventListener()
catches an event, it will pass that event to the callback function as an object.
1let button = document.getElementById("button");
2
3div.addEventListener("click", (event) => {
4 console.log(event);
5});
The event object contains extra information about that event. For example, for the mousedown
event, the event object will tell you exactly which button is pressed, and allow you to define different feedbacks. We will talk more about them in the next lesson.
For now, we need to talk about two commonly used methods that are associated with all event objects.
Stop propagation
The first one is stopPropagation()
. It stops an event from being propagated. For instance, let's continue from our previous example, and use stopPropagation()
on the <p>
element, which sits in the middle.
1div.addEventListener("click", () => {
2 alert("The <div> element is clicked.");
3});
4
5p.addEventListener("click", (event) => {
6 alert("The <p> element is clicked.");
7 event.stopPropagation();
8});
9
10button.addEventListener("click", () => {
11 alert("The <button> element is clicked.");
12});
This time, because the "click"
event is stopped from propagating at <p>
, the event handler attached to <div>
will not be able to receive it.
Prevent default actions
The second method is preventDefault()
. Many elements in the DOM tree has default actions to certain events. The most typical example would be the hyperlink (<a>
). By default, when a link is clicked, it will take you to the destination page. But you can change this default action using the preventDefault()
method.
1<a href="/index.html" id="link">Link</a>
1let a = document.getElementById("link");
2
3a.addEventListener("click", (event) => {
4 alert("Link clicked");
5 event.preventDefault();
6});