How to addEventListener vs. Onclick in JavaScript
This article explains the differences between JavaScript addEventListener
and onclick
.
addEventListener
vs. onclick
in JavaScript
Although both addEventListener
and onclick
can serve the same purpose, there are some nuances that you should know.
So, that’s what this article is all about. What’s more, we’ll accompany our explanations with code examples.
onclick
Is an HTML Attribute; addEventListener
Works Only in the <Script>
Element
onclick
is an HTML attribute so that you can add it directly to an HTML element or within the <script>
element. Meanwhile, you can only use addEventListener
within the <script>
element.
For example, we’ve added onclick
as an attribute of the button
element in the following code. Not only that, the value of the onclick
is a JavaScript alert message.
Therefore, when you click the button, you’ll observe a JavaScript alert in your web browser. However, you cannot add addEventListener
as an HTML attribute.
Example code:
<head>
<meta charset="utf-8">
<title>1-onlick-HTML-attribute-addEventlistener-Via-Script-Element</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #0004ff;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<!-- Add onclick as an attribute of the button -->
<button id="button" onclick="alert('Perform click actions with onclick attribute.')">Default button</button>
</main>
</body>
Output:
In a <script>
element, you can select the button and add onclick
as its attribute. At the same time, you can also add a click event listener to the button using addEventListener
.
So, in the following, the HTML button has the onclick
attribute and addEventListener
. As a result, you’ll get two JavaScript alert messages when you click the button.
Example code:
<head>
<meta charset="utf-8">
<title>1-onlick-HTML-attribute-addEventlistener-Via-Script-Element-V2</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #6800ff;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<button id="button">Default button</button><br/>
</main>
<script>
let button = document.getElementById('button');
// Here, we are in the <script> element, we can
// also add onclick to the button
button.onclick = function() {
alert("Perform click actions with onclick.")
}
// Also add click event via addEventListener
button.addEventListener("click", function() {
alert("Perform click actions with addEventListener");
}, false);
</script>
</body>
Output:
You Can Have Multiple addEventListener
on an Element, but Only One onclick
The addEventListener
allows you to attach multiple click events to an element. However, you can only attach a single onclick
attribute to an element.
Meanwhile, an element will run all the click events added via addEventListener
. So, if an element has three click events via addEventListener
, all will run when you click the element.
The HTML button has two click events via addEventListener
in the code below. When you click the button, all click events will run.
As a result, you’ll observe two JavaScript alert messages in your web browser.
Example code:
<head>
<meta charset="utf-8">
<title>2-Multiple-Events-With-addEventListener-One-with-Onclick</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #ff0054;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<button id="button">Default button</button><br/>
</main>
<script>
let button = document.getElementById('button');
// Also add click event via addEventListener
button.addEventListener("click", function () {
alert("Perform First click action with addEventListener");
}, false);
// Yet another click event via addEventListener
button.addEventListener("click", function () {
alert("Perform Second click action with addEventListener");
}, false);
</script>
</body>
Output:
We’ve mentioned that you can only have one onclick
on an element. However, what happens when you have more than one? Which onclick
will run?
Multiple onclick
Attributes Overwrite Each Other
Only the last one works if you have multiple onclick
on a single element. That’s because onclick
is an element attribute, so only one can exist on the element.
Therefore, your web browser will only execute the last one if you add more than one onclick
to an element.
So, we’ve added two click events via onclick
in the following code. Meanwhile, when you run the code in your web browser, you’ll note the JavaScript alert for the last onclick
.
Example code:
<head>
<meta charset="utf-8">
<title>3-Overwrite onClick</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #a03c32;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<button id="button">Default button</button><br/>
</main>
<script>
let button = document.getElementById('button');
// Define a first click event with onclick
button.onclick = function () {
alert("Perform First click action with addEventListener");
}
// Define another click event with onclick.
// Meanwhile, this one overwrites the first one.
button.onclick = function () {
alert("The second onclick runs, not the first!!!");
}
</script>
</body>
Output:
a String Value of Element.onclick
Fails Silently; addEventListener
Throws an Error
If the function value of onclick
in a <script>
element is a string, it’ll fail silently. However, an error occurs if you supply a string in place of the function in addEventListener
.
In the following example, we have the string Say what?
as the value of button.onclick
. Meanwhile, the same string, Say what?
, is also in the position of the function in addEventListener
.
You’ll get a TypeError
in the console when you run the code. Besides, nothing happens if you click the button, there is no error whatsoever.
That’s because onclick
has a string value instead of a function. Meanwhile, addEventListener
already throws an error at the first run of the code.
Example code:
<head>
<meta charset="utf-8">
<title>4-Onclick-does-not-respond-to-Errors</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #4aa032;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<button id="button">Default button</button><br/>
</main>
<script>
let button = document.getElementById('button');
// This will not throw an error.
button.onclick = "Say what?";
// This throws an error.
button.addEventListener("click", "Say what?")
</script>
</body>
Output:
addEventListener
Gives You Control Over the Number of Clicks; Onclick
Is Always Available
addEventListener
accepts a Boolean value called once
. This value dictates the number of times the listener will run.
So, when you specify once
as true
, the event listener is automatically removed after its first run. In the following code, the button has a click event via onclick
and addEventListener
.
Meanwhile, the addEventListener
has the Boolean once
set to true
. As a result, when you click the button for the first time, you’ll get two JavaScript alert messages.
However, subsequent clicks only show the click event of onclick
. That’s because the addEventListener
no longer exists.
Example code:
<head>
<meta charset="utf-8">
<title>5-Control-addEventListeners-onlclick-always-run</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #5f32a0;
color: #ffffff;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<main id="main">
<button id="button">Default button</button><br/>
</main>
<script>
let button = document.getElementById('button');
// Attach click event via onclick that'll always
// run every time you click the button.
button.onclick = function () {
alert("I always run. Click OK and click the button again.")
}
// We'll execute this function one time, with addEventListener
function sayOnce () {
alert("This is the only time you'll see me. Good Bye.");
}
// You can pass a third Boolean value to addEventListener
// This boolean value defines the number of times you
// the event listener can work on the element. Here,
// the event listener will work once.
button.addEventListener("click", sayOnce, { once: true })
</script>
</body>
Output:
onclick
Can Cause a Memory Leak; addEventListener
Gets Removed With the Element
When you remove an element with a click event via onclick
, the onclick
and its value remain in memory. Check element.onclick
in the removed nodes array of the MutationObserver
to confirm.
The element
is the removed node with onclick
attached. What’s more, you’ll have to set up a MutationObserver
to pull this off.
The two HTML buttons have click events via onclick
in the following code. Meanwhile, clicking on the Remove Parent Button
removes the Parent Button
.
However, with MutationObserver
, we log the onclick
of the Parent Button
to the console. This proves the onclick
still exists even after deleting the Parent Button
.
<head>
<meta charset="utf-8">
<title>6-Memory-Leak-via-Onclick.html</title>
<style>
body {
display: grid;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 1.2em;
background-color: #8832a0;
color: #ffffff;
border: none;
cursor: pointer;
margin-top: 0.2em;
}
</style>
</head>
<body>
<main id="main">
<button id="parent_button">Parent Button</button><br/>
<button id="remove_parent_button">Remove Parent Button</button>
</main>
<script>
let main = document.getElementById('main');
let parent_button = document.getElementById('parent_button');
let remove_parent_button = document.getElementById('remove_parent_button');
// Add a function via onclick
parent_button.onclick = function amIleaking() {
alert("This onclick function exist after the Parent button dies. \n Remove the Parent button, and Check the console!.");
}
// Setup a mutation observer to observe changes
// in the DOM.
const observer = new MutationObserver(function(mutations_list) {
mutations_list.forEach(function(mutation) {
mutation.removedNodes.forEach(function(removed_node) {
if (removed_node.id === 'parent_button') {
console.log('#parent_button has been removed');
observer.disconnect();
}
// Even after removal, the onclick function
// is available in the removedNodes. Here, [0]
// represents the first element of the removed
// node, which the parent_button.
console.log(mutation.removedNodes[0].onclick);
/*To see the function details in Firefox
console.log(mutation.removedNodes[0].onclick.toString());*/
});
});
});
// Observe changes in the main element. Meanwhile,
// the main element consists of the parent button
// and the button that removes it.
observer.observe(document.querySelector("#main"), { subtree: false, childList: true });
// Setup onclick to remove the parent button
remove_parent_button.onclick = function () {
document.querySelector("#parent_button").remove();
}
</script>
</body>
Output:
addEventListener
Does Not Work in IE<9; onclick
Works in IE<9
If you want to support IE<9, addEventListener
will not work. That’s because IE<9 supports the non-standard attachEvent
.
Nevertheless, you can write a utility function if you’d like to support IE<9. This function will check if the web browser supports attachEvent
or addEventListener
.
Therefore, if the browser supports attachEvent
, you’ll use attachEvent
; otherwise, you’ll use addEventListener
. Meanwhile, you can always count on onclick
to work in IE<9.
So, you can use the following code if you want to support IE<9.
Example code:
// Define an addEvent function and check if
// the element supports attachEvent. Otherwise
// we use addEventListner.
function add_event(element, evnt, funct) {
if (element.attachEvent) { // element supports attachEvent
return element.attachEvent('on' + evnt, funct);
} else { // Element does not support attachEvent
// Use addEventListnere instead
return element.addEventListener(evnt, funct, false);
}
}
// How you can use it
add_event(document.getElementById('HTMLElement'), 'click', function() {
alert('Hello World!');
});
Habdul Hazeez is a technical writer with amazing research skills. He can connect the dots, and make sense of data that are scattered across different media.
LinkedIn