Table of contents
- Purpose of the Blog Post
- Overview of Event Handling in JavaScript
- Event
- Event Handling Process
- What is the Event Object?
- Some of the Properties and Methods of the Event Object
- What is the event.target Property?
- How Does event.target Property Works?
- Use Cases for event.target Property
- What is event.currentTarget Property?
- How Does event.currentTarget Property Works?
- Use Cases for the event.currentTarget Property
- event.currentTarget uses for Styling Element
- When to use event.target over event.currentTarget?
- When to use event.currentTarget over event.target
- Conclusion
Purpose of the Blog Post
In this blog post, I will take you into the journey of the world of Javascript. As you might have known, JavaScript is capable of doing wonders.
Or how can you explain the magic of pressing a button on your webpage or application, and it does some lovely things? That is one of the power of Javascript events.
My mission is to share with you, lessons about event handling, where we'll explore how JavaScript listens to these special events like the click, input, mouseenter, and the rest. The event objects hold information about the event itself.
The event.target
shows the element that gets clicked and interacted with. The event.currentTarget
pinpoints the actual element where the event was first heard, irrespective of how far it traveled.
I will also show the difference between event.target
and event.currentTarget
. If you are excited about learning and understanding all these concepts, let's dive in and have fun together.
Overview of Event Handling in JavaScript
In this section, we will discuss the overview of event handling in JavaScript. Here, we will discuss the event, event handling process, event phase, event delegation, and many more.
Event
An event
, which exists in all programming languages, can be called by different actions like time intervals, clicks, and mouse movement.
In JavaScript, an event provides an interactive and dynamic interface to a webpage or an application. The purpose of events in JavaScript is to execute code whenever a specific event occurs.
There are wide ranges of event types like the clicking of buttons, submitting a form
, page load
, data from the server, etc. which are supported by JavaScript.
Event Handling Process
An event handler
is akin to a multi-purpose doorbell with functions like communicating, visitor notifications, security, and convenience is available for auction. But the only issue attached to the doorbell is that it has a hidden button that must be operated by a professional.
The above illustration explains the concepts of handling events in JavaScript. The application or webpage represents the multi-purpose doorbell. The hidden special button is the HTML-like button on the application. To handle the special button, the professional needed is JavaScript.
With event handling, an application and webpages are made to be interactive and responsive. By, first defining, and subsequently managing events whenever those events occur.
Event Listener
In JavaScript, an event listener
is a way of waiting for user interaction like mouseover
or a click
and executing some code whenever an action occurs.
const button = document.getElementById("check");
button.addEventListener("click", function (e) {
console.log(e.type);
console.log("Yes");
});
It is easy to set up an event listener. All you need is a reference to an element on your webpage and store it in a variable. Then, call the addEventListener()
method on that variable. The addEventListener()
takes a minimum of two parameters and a maximum of three parameters.
The first parameter string
is the name of the event you want to listen to.
There are numerous events you can listen to such as input, mousemove, click, and so many more. The second parameter of the addEventListener()
is the function known as the callback function with a single argument e
that runs every time the specific event occurs on that element.
In the above code, the function will print the e.type and Yes to the console whenever the button gets clicked. The third parameter is an optional boolean value, with the default value of false
.
Event Phase in JavaScript
Events in the DOM
Document Object Model generally propagated in three phases, namely the bubbling
,target
, and capturing
phases.
The Bubbling
phase is where the event moves up from the target element to the global objects. By default, all events added with the addEventListener()
method are propagated in the bubbling phase.
const parent = document.querySelector("ul");
const child = document.querySelector(" button");
parent.addEventListener("click", function () {
console.log("Ul was clicked");
});
child.addEventListener("click", function () {
console.log("Button was clicked");
});
When an event bubble up
it moves through all the ancestor element after it has been processed at the target element. In the code example above, the event moves from the target element button which is a child element, up through the parent ul
which is the parent element.
The result shows the event listener on the parent was logged to the console after the event listener on the child. With event bubbling, it is easier to implement event delegation.
The target
phase occurs after the capturing phase but before the bubbling phase. If you attach an event handler to a button on your webpage, the button automatically becomes the target element for the event.
Capturing
phase occurs when a child element nested in a parent or ancestor element gets clicked. The click event of the parent must be triggered before the click event of the child.
This happens when the optional third argument of the event listener gets changed from the default false
to a true boolean value.
const parent = document.querySelector("ul");
const child = document.querySelector(" button");
parent.addEventListener("click", function () {
console.log("Ul was clicked");
},true);
child.addEventListener("click", function () {
console.log("Button was clicked");
});
Whenever we change the value of the third argument of addEventListener()
to true
, event handlers get triggered in the capturing phase. In the above code example, the event clicks event handler attached to the parent element ul
will be executed first before the click event on the child button.
event.stopPropagation() method
The event.stopPropagation()
method modifies the default configuration of the event handlers, which happens in the bubbling phase (from the target to the ancestor elements).
As implied by its name, the event.stopPropagation()
method puts a stop to any propagation.
const parent = document.querySelector("ul");
const child = document.querySelector(" button");
parent.addEventListener("click", function () {
console.log("Ul was clicked");
});
child.addEventListener("click", function (event) {
console.log("Button was clicked");
event.stopPropagation();
});
The code above shows how the event.stopPropagation()
method prevents the click event attached to the parent element ul
from showing in the console.
Event Delegation
Controlling a few people is achievable, albeit stressful, but it is almost impossible to control thousands of people. Imagine a large seminar made up of several mini-seminars with thousands of attendees. To solve the issue of rowdiness, it's advisable to have a single receptionist at the main entrance, who will direct each attendee to their respective seminar room, instead of having many receptionists at mini-seminar room entrance.
The above scenario is similar to the event delegation
concept in JavaScript. Event delegation capitalizes on the DOM
(Document Object Model) bubbling event by setting the event listener on the ancestor element.
This allows for easier handling of events, unlike setting events individually on elements to trigger events. As said earlier, events on the child rise to their parent element in the bubbling phase. See the code for more clarity.
const parent = document.querySelector("ul");
parent.addEventListener("click", function () {
console.log(this);
console.log('I clicked the li');
});
In the above code, the ul
which is the parent element of the li
will handle the event by delegating the logic to the child. As aware, the li
bubbles up in the DOM
tree.
What is the Event Object?
In JavaScript, an event object
is simply a parameter automatically passed into an event handler function also known as a call-back function. Whenever an event transports data, an object that contains contextual information about the events gets created.
The information obtained from the object can include but is not limited to the type of event that occurred, the target element on which the event occurred, and so on. Therefore, it will make it easy to access the event data and respond appropriately.
In the case of the addEventListener()
method, where we define the event handler function ourselves, it is the convention to name the parameter as e
or event but you can decide to name the parameter whatever you like.
// Created a variable of a button that gets a button element with an id of the button
const button = document.getElementById("button");
// Add the event listener method to the button
button.addEventListener("click", function (e) {
// The e in the event handler function is the event object
console.log(Event, e.target);
// We console log the event.target which is the button element itself
console.log(Event, e.type);
// We console log the event.type which is the click event listener
});
The above code shows the event object represented by e
, and we were able to log in to the console, the e.target
and the e.type
.
Some of the Properties and Methods of the Event Object
It is no longer news that numerous types of event interfaces occur on a webpage based on the event interfaces. Nevertheless, the event itself contains properties and methods that are common to all events, as the event interface is known to be the bedrock of JavaScript event objects. Some of the interfaces based on events are the dragEvent
, blobEvent
, closeEvent
, fetchEvent
, focusEvent
, and so on.
In this section, we'll take a look at some of the properties, and methods of the event objects in JavaScript.
- Event.type:
event.type
is a read-only property that specifies the type of the specific event, such as load, click, and so on. The return value is a string that indicates the event type that occurred. Theevent.type
property is regularly used in determining the type of event that occurred, and to run specific code based on the the result.
// Created a variable of a button that gets a button element with an id of the button
const button = document.getElementById("button");
// Add the event listener method to the button
button.addEventListener("click", function (e) {
// We console log the event.type
console.log(Event, e.type);
});
From the above code, the string
value of the click was logged to the browser.
- Event.bubbles: The
event.bubbles
is a read-only property that cannot directly be set. It is a boolean value that shows whether the event bubbles up during event propagation. The event will bubble up if the booleanevent.bubble
property istrue
, and won't if the value isfalse
.
const button = document.getElementById("button");
button.addEventListener("click", function (event) {
if (!event.bubbles) {
console.log(' This click event won"t bubble up');
} else {
console.log("This click event will bubble up.");
}
});
The above code will log the "This click event will bubble up" to the console. This happened because we checked if the event.bubbles
is not a boolean value of true
. The result will be different if we check the boolean value of the event.bubbles
is true
. Because by default, most events propagate in the bubbling ` phase.
- Event.cancelable: The
event.cancelable
is a read-only property of the event. It is a boolean value property of the event indicating the cancelable status of the event. The event is cancelable by calling theevent.preventDefault()
method if theevent.cancelable
boolean value istrue
. But, the event is not cancelable if the boolean value isfalse
. Some events likeDOMContentLoaded
or resize which do not have a default action can't be canceled. However, some other events like thewheel
,click,
andkeydown
are cancellable to prevent their default behavior.
const button = document.getElementById("button");
button.addEventListener("click", function (event) {
if (event.cancelable) {
event.preventDefault();
console.log(" This click event has been canceled");
} else {
console.log("This click event is up and running.");
}
});
The above code prevents the default action of the click, and logs the message "This click event has been canceled". But, the message will be This click event is up and running if the click event is not cancelable.
- Event.eventPhase: The
event.eventPhase
is a read-only property of the event, which indicates the actual phase of the event propagation. It's also an integer value base specifying the current phase of the event flow.
Event.NONE (0): This is the phase where the event is not currently processed.
Event.CAPTURING_PHASE (1): The propagation of the event through the target ancestor element. This phase represents the capture phase.
Event.AT_TARGET (2): The arrival of the event at the event's target element. This value represents the target phase in the event flow phase.
Event.BUBBLING_PHASE (3): The movement of the event back up from the target element to the root of the DOM
tree. This phase is known as the bubbling phase, which occurs only if the value of the event.bubbles
property is true
.
const button = document.getElementById("button");
const div = document.getElementById("div");
const parent = document.querySelector("div");
parent.addEventListener("click",function (event) {
switch (event.eventPhase) {
case Event.CAPTURING_PHASE:
console.log("Capture phase");
break;
case Event.AT_TARGET:
console.log("Target phase");
break;
case Event.BUBBLING_PHASE:
console.log("Bubbling phase");
break;
}
},
true,
);
div.addEventListener("click", function (event) {
switch (event.eventPhase) {
case Event.CAPTURING_PHASE:
console.log("Capture phase");
break;
case Event.AT_TARGET:
console.log("Target phase");
break;
case Event.BUBBLING_PHASE:
console.log("Bubbling phase");
break;
}
});
button.addEventListener("click", function (event) {
switch (event.eventPhase) {
case Event.CAPTURING_PHASE:
console.log("Capture phase");
break;
case Event.AT_TARGET:
console.log("Target phase");
break;
case Event.BUBBLING_PHASE:
console.log("Bubbling phase");
break;
}
});
Each event listener listens for the click
event and logs messages based on the event phase, whether it's the capturing phase, at the target
, or the bubbling phase. The addEventListener method is used with the third argument true on the parent element to enable the capturing phase for this listener.
The above code explains more about the event flow phase in JavaScript. There are three different elements, with each having its click event listener. The event listeners listen for the event and log messages based on whether the event phase is capturing the target, or bubbling phase.
By critically looking at the code, the parent element has its third argument set to true
, which indicates a capturing phase. There will be different messages logged into the console, whenever you click on these elements.
When you click on the button, which is a child element to the parent element, the message from the console will be:
The explanation for the result is that, when the button gets clicked, the event listener attached to the button by default should bubble up
. But, it doesn't. The third argument of the parent event listener has been changed to the capturing phase by changing the boolean
value to true
.
When the div
gets clicked, the message from the console will be:
Similar to the above, when the div
gets clicked, the event listener attached to the div
by default should bubble up. But, it doesn't. The third argument of the parent event listener has been changed to the capturing phase by changing the boolean value to true
.
And lastly, when the parent elements get clicked, the message from the console will be:
Two important event properties will be discussed in the subsequent section. They are the event.target
and the event.currentTarget
.
- Event.preventDefault(): The
event.preventDefault()
method in JavaScript prevents the default behavior of an event from occurring. This can only happen if the said event does not get explicitly handled. Theevent.preventDefault()
method can be used to prevent the default behavior of the form submission, the anchor taga
element for preventing links from opening on another page, and the default behavior of the keyboard event.
const checkbox = document.querySelector("#checkbox");
checkbox.addEventListener("click", function (e) {
e.preventDefault();
console.log("yes");
});
The above code selects an input
of checkbox type, with an id
of checkbox using the popular document.querySelector()
method. A click event was then attached to the selected element. Whenever the element gets clicked, it prevents the default behavior of a checkbox input element. Hence, it only logs the string
"yes" to the console.
- Event.stopPropagation(): The JavaScript
event.stopPropagation()
method prevents continuous propagation of an event depending on where it is called in your event listener through either the capturing or the bubbling phase. It is worth noting that it however does not prevent the default behaviours from occuring.
const ul = document.querySelector("ul");
const Li = document.querySelectorAll("li");
ul.addEventListener("click", function () {
console.log("parent");
});
Li.forEach((list) => {
list.addEventListener("click", function (e) {
e.stopPropagation();
console.log("child");
});
});
The above code stops the default bubbling propagation. By default, when a child element nested in a parent element gets clicked, it will bubble up
to the parent element. Hence, the event listener of the parent element gets triggered as well. However, the parent element event listener will be triggered after the event listener of the child element. i.e. the "child" will be logged before the "parent" gets logged into the console. But, with the event.stopPropagation()
method attached to the child element, it won't propagate to the parent element.
const ul = document.querySelector("ul");
const Li = document.querySelectorAll("li");
ul.addEventListener("click",function (event) {
event.stopPropagation();
console.log("parent");
},
true,
);
Li.forEach((list) => {
list.addEventListener("click", function (e) {
console.log("child");
});
});
There are a couple of changes implemented in the above code. Firstly, the propagation method was changed from the default bubbling to the capturing phase. By setting the third argument of the parent event listener to the boolean value of true
. Secondly, the event.stopPropagation()
method was attached to the parent element. The implication here is that, if either the parent or the child element gets clicked, only the "parent" will be logged into the console.
- Event.stopImmediatePropagation(): The JavaScript
event.stopImmediatePropgation()
method is used to prevent any further events from being executed, including those from the same element, while also stopping the propagation of an event. This method is similar to theevent.stopPropagation()
method but with the ability to prevent other event listeners on the same element from executing.
const ul = document.querySelector("ul");
const Li = document.querySelectorAll("li");
ul.addEventListener("click", function (event) {
console.log("parent");
});
Li.forEach((list) => {
list.addEventListener("click", function (e) {
e.stopImmediatePropagation();
console.log("child");
});
});
Li.forEach((list) => {
list.addEventListener("click", function (e) {
console.log("Good");
});
});
The above code explains that when you click on the same li
element, the "child" will be the only message logged into the console. Why? Because we added the event.stopImmediatePropagation()
method to the first event handler in our code.
It means we have stop both the default propagation, and the other event listeners added to the li
element. This clearly shows how we can control event propagation, most especially when event.stopImmediatePropagation()
is used.
What is the event.target Property?
During my explanation of some of the event properties, I briefly mentioned some properties we would discuss later. Now is the later, and we will talk about the event.target
property.
The event.target
is a read-only event property, that is commonly used in determining which HTML element dispatches an event. The word "target" also known as "prey" simply means to "aim at something". Hence, event.target
provides a reference to the element, by aiming at that particular element to access, and manipulate both the element and its properties.
There is a difference betweenevent.target
and event.currentTarget
. While event.target
returns a reference to the object that triggers the event, irrespective of whose element listens to the event, the event.currentTarget
returns a reference to the object that triggered the event.
How Does event.target Property Works?
The JavaScript event.target
is a popular property, used in event handling for providing reference to an element that executes an event. The starting point of using an event.target
property is to create a variable for an HTML element, and then attach an event listener like the mouseover
, click
, and keydown
to that element(s).
const LI = document.querySelectorAll("li");
LI.forEach((list) => {
list.addEventListener("click", function (e) {
// YOUR CODE HERE
});
});
In the above code, a click event listener was attached to a single li
element.
The event listener function also known as the callback function which receives an event object that contains information about the event as a parameter, is then called when click event listener occurs on the HTML element.
Right inside the callback function, the element that executes the event can be known through the event.target
property.
const LI = document.querySelectorAll("li");
LI.forEach((list) => {
list.addEventListener("click", function (e) {
console.log(e.target);
});
});
`
The above code shows that with the event.target
property, the HTML element can be easily manipulated, and any information about the element can be easily gotten.
Use Cases for event.target Property
There are a couple of use cases for event.target
in an application. Now, we will discuss two use cases for event.target
.
event.target uses in Event Delegation
As earlier said, event delegation allows for easier handling of events, by setting event listeners on an ancestor element instead of setting events individually on elements to trigger the event. Hence, the event.target
is an integral part of the event delegation.
Because, it's the property that determines which child of the ancestor triggers the event, whenever the event bubbles up
to the parent element.
const ul = document.querySelector("ul");
ul.addEventListener("click", function (event) {
if (event.target.textContent === "Orange") {
console.log("yes");
} else {
console.log("no");
}
});
The above code uses event delegation, by attaching a single event to the parent element ul
in this case. Recall that by default, events propagate up from the target element to the root of the document. It is therefore easy to access the event.target
property.
By using the event.target
property in the code, it is easy to identify the child element that triggered the event. A conditional logic was then added to check if the text content of the target is "Orange", and run some code. Or, run another code if the target text content is not "Orange".
event.target Uses to get Properties
One of the most common uses of event.target
is to get properties, most especially in the input element. A change event, which is fired once there is a change in input element content can be listened to in an input
element field.
const input = document.querySelector("input");
const h2 = document.querySelector("h2");
input.addEventListener("change", function (event) {
h2.innerHTML = event.target.value;
});
The above code sets a variable reference to the input
tag, and an empty h2
tag. A change event listener was then listened to on the input. Theevent.target
is then used to get the value of the input, and hence set the value to the innerHTML of the empty h2
.
What is event.currentTarget Property?
The JavaScript event.currentTarget
is a read-only property of the event used while working with event handling. It refers to the element to which the event handler has been attached, which may or may not be the same as the event.target
element.
It's a useful property in event delegation that allows for easy access to the element handling the event, which is mostly different from the element that got the event triggered.
How Does event.currentTarget Property Works?
The JavaScript event.currentTarget
property is important when using the event delegation to gain access to the element that triggers the event handler.
The starting point of using an event.currentTarget
property is to create a variable for an HTML element, and then attach an event listener like the click
, keydown
, and mouseover
to that element(s).
const UL = document.querySelector("ul");
const LI = document.querySelectorAll("li");
UL.addEventListener("click", function (event) {
console.log(event.target);
console.log(event.currentTarget);
});
In the above code, a click event listener was attached to the parent element UL.
The event listener function also known as the callback function which receives an event object that contains information about the event as a parameter, is then called when click event listener occurs on the HTML element.
The li
which is the child element will be logged as the event.target
while the parent ul
will be logged as the event.currentTarget
.
Use Cases for the event.currentTarget Property
Just like the event.target, there are numerous ways to use the event.currentTarget
in an application. Now, we will discuss two use cases for event.currentTarget
.
event.currentTarget uses in Event Delegation
Whenever you have a group of elements, it is easy to attach a single event listener to the parent container. Take, for instance, the ul
element with multiple li
items.
Instead of attaching an event listener to the ul
, all the list items will be selected through the popular querySelectorAll()
method.
const LI = document.querySelectorAll("li");
LI.forEach((list) => {
list.addEventListener("click", function (e) {
console.log(e.currentTarget);
});
});
In the above code, the document.querySelectorAll()
method was used to select all the li
elements in the document. Then, the forEach
higher order array method, was used to iterate over theli
items. Furthermore, a click event listener was then attached to each li
element.
Whenever each li
gets clicked, the event object is generated, and the e.currentTarget
property refers to the actual element currently handling the click event.
In summary, when any li
gets clicked, the actual li
will be logged to the console. This is crucial for the effective handling of individual item interactions.
event.currentTarget uses for Styling Element
The event.currentTarget
can be used for changing the styling of an element in a document.
const UL = document.querySelector("ul");
const LI = document.querySelectorAll("li");
UL.addEventListener("click", function (e) {
e.currentTarget.style.backgroundColor = "blue";
});
LI.forEach((list) => {
list.addEventListener('click', function(e) {
if (e.currentTarget.textContent === 'Orange') {
e.currentTarget.style.textTransform = 'uppercase';
}
})
The above code shows how the styling of both the ul
and the li
is changed with e.currentTarget
. After creating variables for both the parent element ul
, and the child element the li
.The child element, after iterating over the list, together with the parent element got event listeners attached to them.
In the child event listener, we conditionally checked if the text content of the event.currentTarget
is 'Orange', and transformed the text to uppercase if true, otherwise, we return the status quo, this is done in addition to changing the background color of the parent element.
When to use event.target over event.currentTarget?
Although both the event.target
, and the event.currentTarget
are two of the many properties of events object in Javascript, they serve different purposes.
When there's a nested element, and there's a need to identify the element that get interacted with, the event.target
should be used.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<ul id="parent">
<li>Orange</li>
<li>Banana</li>
<li>Apple</li>
</ul>
<script>
const parent = document.getElementById("parent");
parent.addEventListener("click", function (event)
{console.log(event.target)});
</script>
</body>
</html>
The above code will log the specific li
that gets clicked.
When to use event.currentTarget over event.target
The best time to use the event.currentTarget
property over the event.target
property is when you need to get a reference to the element that handles the event listener. This is helpful during event delegation, when there are nested elements, and would like to identify the specific element that triggered the event.
It is also crucial when you need to perform a specific action on a parent element, irrespective of whose child was clicked.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<div id="parent">
<button id="first">Click ME</button>
<button id="second">Click Me 1</button>
</div>
<script>
const parent = document.getElementById("parent");
parent.addEventListener("click", function (event)
{console.log(event.currentTarget.id)});
</script>
</body>
</html>
In the above code, the attached event listener will be triggered when there's a click on any of the child elements. As said above, the event.currentTarget
property regardless of the child element that gets clicked, will return the parent element, in this case, the div
element.
Conclusion
With this detailed guide, you now have a clearer understanding of JavaScript capabilities, how it listens to events, holds information about the events, and the difference between event.target
, and event.currentTarget
.