How to click the grand child element without also clicking its grandparent?

Viewed 54

So I want to toggle the class named "active" for
<section class="showcase"> and <div class="toggle"></div>
when only <div class="toggle"></div> is clicked.

However, when either <section class="showcase"> OR <div class="toggle"></div> is clicked
I want to remove that "active" class from both <section class="showcase"> and <div class="toggle"></div>
so I can close my menu.

HTML Structure:

<section class="showcase">
        <header>
            <h2 class="logo">Travel</h2>
            <div class="toggle"></div>
        </header>
</section>

JavaScript attempt to achieve what I described above:

const menuToggle = document.querySelector(".toggle")
const showcase = document.querySelector(".showcase")

menuToggle.addEventListener("click", () => {
    menuToggle.classList.toggle("active")
    showcase.classList.toggle("active")
})

showcase.addEventListener("click", () => {
    if (showcase.classList.contains("active") || menuToggle.classList.contains("active")) {
        menuToggle.classList.remove("active")
        showcase.classList.remove("active")
    }
})
2 Answers

You could use the event.stopPropagation(), so when clicking the .toggle, the event doesn't bubble to the parent:

const menuToggle = document.querySelector(".toggle")
const showcase = document.querySelector(".showcase")

menuToggle.addEventListener("click", (e) => {
    e.stopPropagation()
    menuToggle.classList.toggle("active")
    showcase.classList.toggle("active")
})

showcase.addEventListener("click", () => {
    if (showcase.classList.contains("active") || menuToggle.classList.contains("active")) {
        menuToggle.classList.remove("active")
        showcase.classList.remove("active")
    }
})

this way: Only one event listener is enough

const showcase   = document.querySelector('section.showcase')
  ,   menuToggle = document.querySelector('div.toggle')
  ;
showcase.onclick = e =>
  {
  if ( showcase.classList.contains('active') )
    {
    menuToggle.classList.remove('active')
    showcase.classList.remove('active')
    }
  else if (e.target.matches('div.toggle'))
    {
    menuToggle.classList.add('active')
    showcase.classList.add('active')
    }
  }
section.active { background-color: aqua;}
div.active { background-color:yellow;}
<section class="showcase">       
  <header>
    <h2 class="logo">Travel</h2>
    <div class="toggle">divToggle </div>    
  </header>
</section>

Related