'JavaScript, clicking button activates two event listeners

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 class="page">


        <div class="nav-container" onclick="hamburger(this)">
            
            <div class="ham-container">
                <div class="hamburger-1"></div>
                <div class="hamburger-2"></div>
                <div class="hamburger-3"></div>
            </div> 

            <div class="nav-bar">
                <a>Home</a>     
                <a>Services</a>     
                <a>About</a>    
                <a>Projects</a>
            </div>



            <div class="button-test">
                <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?



Solution 1:[1]

When you trigger an event on an element, it will sequently be triggered for its father, for its grandfather... all the way to the last parent element. Often we don't see this behaviour happening because often we have one event listener in an element family.

But if the triggered element is inside a parent that has an event listener for the same event, like in your close with the click event, both of them will be triggered. However you can prevent this behaviour with the help of stopPropagation method, this way:

function clickTest(e) {
  e.stopPropagation();
  i++;
  console.log(i)
}

Solution 2:[2]

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)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2