I have two buttons on my page that I use to try new things. Both of them use the "onclick" linked to a different JS function. For some reason the second one activates both? And I can't figure out what I've done wrong.
The HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<link HREF="styleTest.css" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto Serif:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
<script type="text/javascript" src="script.js"></script>
<title>TEST</title>
</head>
<body>
<div >
<div onclick="hamburger(this)">
<div >
<div ></div>
<div ></div>
<div ></div>
</div>
<div >
<a>Home</a>
<a>Services</a>
<a>About</a>
<a>Projects</a>
</div>
<div >
<button onclick="clickTest()">CLICK ME</button>
<h1>Test text</h1>
</div>
</div>
</body>
And the two JS functions:
function hamburger(x) {
x.classList.toggle("change");
}
var i =0
function clickTest() {
i ;
console.log(i)
}
What am I doing wrong?
CodePudding user response:
When you trigger an event on a child element that is inside a parent that has an event listener for the same event, it will trigger both of them. It is called propagation. However you can prevent this behaviour with the help of stopPropagation
method.
function clickTest(e) {
e.stopPropagation();
i ;
console.log(i)
}
CodePudding user response:
This happens because of a concept known as Bubbling in DOM .
When an event happens on an element, it first runs the handlers on it, then on its parent, then all the way up on other ancestors.
Try playing around with this snippet below .
<style>
body * {
margin: 10px;
border: 1px solid blue;
}
</style>
<form onclick="alert('form')">FORM
<div onclick="alert('div')">DIV
<p onclick="alert('p')">P</p>
</div>
</form>
A click on the inner <p>
first runs onclick:
On that <p>
.
Then on the outer <div>
.
Then on the outer <form>
.
And so on upwards till the document object.
Please refer this page for more clarity : Link
CodePudding user response:
The way event listeners works is that when you have a nested object
(For example button inside a div)
And both of them has event listeners , when you click on the inner element (button) the event listener of the button
will first be fired before the parent event listener
To solve this, you have to stop the propagation using this code
<button onclick="clickTest(event)">CLICK ME</button>
And the script
function clickTest(e) {
e.stopPropagation();
i ;
console.log(i)
}