To get a job as a front-end developer, we need to nail the coding interview.
In this article, we’ll look at questions about handling events within front-end JavaScript.
How Are Event Handlers Used in JavaScript?
Events are actions that result from user activities like clicking a link or typing in text. An event handler is required to run code when an event is triggered in an element.
Event handlers are set as an extra property of an object. For example, if we want to handle an event of a button, then we can write:
const button = document.getElementById('button');
button.onclick = (event) => {
//...
}
Assuming the button’s ID is button
, we can attach an onclick
listener to handle click events by setting an event handler function to the onclick
property.
The event
parameter is an object that has various pieces of information about the event.
We can also use the addEventListener
call to do the same thing:
const button = document.getElementById('button');
button.addEventListener('click', (event) => {
//...
})
The first argument has the event name. The event listener is in the second argument of the addEventListener
method call.
What’s the difference between ‘event.preventDefault()'
and ‘event.stopPropagation()'
?
event.preventDefault()
is used to stop the default behavior of whatever element that triggered the event from happening.
If it’s used with a form
element, then we prevent it from submitting.
If it’s used with an a
element, then preventDefault()
prevents it from navigating.
event.stopProgation()
is specifically used to stop the propagation of an event and stops an event from occurring in the bubbling and capturing phase.
How Do We Know If ‘event.preventDefault()'
Was Used in an Element?
We can check the event.defaultPrevented
property in the event object. If it’s true
, then event.preventDefault()
was called.
What’s ‘event.target’?
event.target
is the element on which the event occurred or the element where the event was triggered.
For example, let’s say we have the following HTML:
<div id='div'>
<button id='button'>
Click Me
</button>
</div>
And the following JavaScript code:
const button = document.getElementById('button');
button.onclick = (event) => {
console.log(event.target.id);
}
When we click the Click Me
button, we’ll get button
from the console.log
since it’s where the click event originated.
This shows that event.target
is the element where the event was triggered.
If we add an event handler for the div, as follows:
const button = document.getElementById('button');
const div = document.getElementById('div');
button.onclick = (event) => {
console.log(event.target.id);
}
div.onclick = (event) => {
console.log(event.target.id);
}
We also get button
logged in there, so event.target
is definitely the element where the click event was originated.
What’s ‘event.currentTarget’?
event.currentTarget
is the element which attached the event handler explicitly.
For example, say we have the following HTML:
<div id='div'>
<button id='button'>
Click Me
</button>
</div>
And this JavaScript:
const button = document.getElementById('button');
const div = document.getElementById('div');
button.onclick = (event) => {
console.log(`button.onclick ${event.currentTarget.id}`);
}
div.onclick = (event) => {
console.log(`div.onclick ${event.currentTarget.id}`);
}
When we click the Click Me
button, we see button.onclick button
logged from the button.onclick
event handler and div.onclick div
logged from the div.onclick
event handler.
Therefore, we see event.currentTarget
is the element we attached to the event handler.
What’s Event Delegation?
Event delegation is where we add event listeners to the parent element instead of adding them to the descendant elements.
The listener will fire on whatever element triggered on the descendant because events bubble up from the element that triggered the event.
It’s useful because we only have a single handler attached to the parent element.
There’s also no need to unbind the handler from the element that’s removed and to bind it to new elements.
For example, if we have the following HTML …
<div id='div'>
<button id='button-a'>
Click Me
</button>
<button id='button-b'>
Click Me
</button>
</div>
… then we can write the following JavaScript code to add event delegation:
const div = document.getElementById('div');
div.onclick = (event) => {
if (event.target.matches("button#button-a")) {
alert('Button A clicked');
} else if (event.target.matches("button#button-b")) {
alert('Button B clicked');
}
}
In the code above, get the div
by ID, and then attached a click-event handler to it.
Then, in the event-handler function, we check the event.target
that invoked the click event by using the matches
method.
If the button with the ID button-a
is clicked, then we show an alert box with Button A clicked
.
And if the button with ID button-b
is clicked then we show an alert box with Button B clicked
.
As we can see, we only have one event handler, but we did can handle the click events of all the buttons inside.
What’s the Difference Between the Document-Load
Event and the Document DOMContentLoaded
Event?
The DOMContentLoaded
event is fired when the initial HTML document has been completely loaded and parsed without waiting for style sheets, images, and subframes to finish loading.
The load
event is only fired after the DOM and all dependent resources and assets have been loaded.
What’s an Event Loop?
The event loop is a single-threaded loop that watches the call stack and checks if there’s any code to run in the task queue.
If the call stack is empty and there’re callback functions in the task queue, then they’ll be dequeued from the task queue and run by pushing them to the call stack.
Conclusion
In JavaScript, we handle events by attaching event listeners to an element.
We can also use event delegation to avoid attaching event listeners to each element. It’s also helpful for handling dynamic-element events since we don’t have to attach and remove event listeners from them with event delegation.
In JavaScript, the event loop is a single-threaded loop that watches the call stack and runs what’s there. If there’s nothing in the call stack, then whatever is in the task queue will be dequeued and run by pushing it to the call stack.