简体   繁体   中英

Toggle active class to buttons when clicked

With the current code written, I am able to select the first button with a class of mobile__CTA--btn and toggle the "active" class when clicked. When I click on the next button to try to toggle the "active" class, the first button gets the class unassigned yet I am not able to assign the "active" class to the next button. Any suggestions?

 const callToActionBtns = document.querySelectorAll(".mobile__CTA--btn"); callToActionBtns.forEach((btn) => { btn.addEventListener("click", (e) => { const currentBtn = e.target.parentElement.querySelector(".mobile__CTA--btn"); currentBtn.classList.toggle("active"); }); });
 .active { color : white; border-bottom : 5px solid $purple; padding-bottom : 1rem; }
 <div class="mobile__CTA"> <button id="overview-btn" class="mobile__CTA--btn"> OVERVIEW </button> <button id="structure-btn" class="mobile__CTA--btn"> STRUCTURE </button> <button id="surface-btn" class="mobile__CTA--btn"> SURFACE </button> </div>

This:

const currentBtn =
      e.target.parentElement.querySelector(".mobile__CTA--btn");
currentBtn.classList.toggle("active");

Gets the parent div container, finds the first element with the class mobile__CTA--btn (which is the first button) and toggles the class.

You should instead be looping through callToActionBtns and removing the class active , then toggling the active class for the event target:

 const callToActionBtns = document.querySelectorAll(".mobile__CTA--btn"); callToActionBtns.forEach((btn) => { btn.addEventListener("click", (e) => { callToActionBtns.forEach(f => f.classList.remove('active')); e.target.classList.toggle("active"); }); });
 .active { color: white; border-bottom: 5px solid $purple; padding-bottom: 1rem; }
 <div class="mobile__CTA"> <button id="overview-btn" class="mobile__CTA--btn">OVERVIEW</button> <button id="structure-btn" class="mobile__CTA--btn">STRUCTURE</button> <button id="surface-btn" class="mobile__CTA--btn">SURFACE</button> </div>

If you want to have the ability to untoggle the current button, just add an if statement while looping that checks whether the item currently being looped through is the target element:

 const callToActionBtns = document.querySelectorAll(".mobile__CTA--btn"); callToActionBtns.forEach((btn) => { btn.addEventListener("click", (e) => { callToActionBtns.forEach(f => f != e.target ? f.classList.remove('active') : ''); e.target.classList.toggle("active"); }); });
 .active { color: white; border-bottom: 5px solid $purple; padding-bottom: 1rem; }
 <div class="mobile__CTA"> <button id="overview-btn" class="mobile__CTA--btn">OVERVIEW</button> <button id="structure-btn" class="mobile__CTA--btn">STRUCTURE</button> <button id="surface-btn" class="mobile__CTA--btn">SURFACE</button> </div>

Simply use an arrow function to keep btn reference into the event listener :

 const callToActionBtns = document.querySelectorAll('.mobile__CTA--btn'); callToActionBtns.forEach((btn, _, AllBtn) => { btn.onclick = e => { if ( btn.classList.toggle('active')) AllBtn.forEach( btx => btx.classList.toggle('active', btx===btn )) } })
 .active { color : white; border-bottom : 5px solid $purple; padding-bottom : 1rem; }
 <div class="mobile__CTA"> <button id="overview-btn" class="mobile__CTA--btn"> OVERVIEW </button> <button id="structure-btn" class="mobile__CTA--btn"> STRUCTURE </button> <button id="surface-btn" class="mobile__CTA--btn"> SURFACE </button> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM