How to ensure only one tab is coloured upon clicking?

Viewed 81

I'm trying to write a function such that when you click a tab (created using bootstrap) it changes to a gold color. This bit works fine, however, I want to toggle the active property of each tab (bootstrap) so that it's on to give a nice white outline. The issue is unless you click on the same tab again, it stays white. Any ideas? Thanks.

This is my work so far:

let timesClicked = 1;

let navItems = document.querySelectorAll('.changeColor');
navItems.forEach(item => {
  item.addEventListener("click", () => {
    timesClicked++;
    console.log(timesClicked);
    let previousItem = item;
    if (timesClicked % 2 == 0) {
      item.style.color = "#f0a500";
      item.classList.toggle('active');
      console.log(item);
    } else {
      previousItem.classList.toggle('active');
      console.log(previousItem);
    };

    navItems.forEach(otherItem => {
      if (otherItem !== item) {
        otherItem.style.color = "#1A1C20";
        /*
        item.addEventListener("click", () =>
          item.classList.toggle('active'));
       ;*/
      };
    });

  });
})
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab"
      aria-controls="Mathematics" aria-selected="true">Mathematics</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab"
      aria-controls="profile" aria-selected="false">English</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab"
      aria-controls="contact" aria-selected="false">Verbal</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab"
      aria-controls="contact" aria-selected="false">Nonverbal</a>
  </li>
</ul>

3 Answers

Based on your code, I did following steps to correct it:

  1. set first tab as the default active one before clicking.
  2. when click on any tab, deactive previous tab, and remember this active one by the variable previousItem(you should declare this variable outside forEach(..)).

let navItems = document.querySelectorAll('.changeColor');
let previousItem = navItems[0];

navItems.forEach(item => {
  item.addEventListener("click", () => {

    if(previousItem == item)return;

    item.style.color = "#f0a500";
    item.classList.toggle('active');

    previousItem.classList.toggle('active');
    previousItem.style.color = "#1A1C20";

    previousItem = item;
 });
})
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab"
      aria-controls="Mathematics" aria-selected="true" style="color:#f0a500;">Mathematics</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab"
      aria-controls="profile" aria-selected="false">English</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab"
      aria-controls="contact" aria-selected="false">Verbal</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab"
      aria-controls="contact" aria-selected="false">Nonverbal</a>
  </li>
</ul>

You are over complicating your code this can simply be done using querySelectorAll and forEach method.

Just remove the active class and color from all the nav items and then add only to the clicked menu item only using Event.target method

Simplified code Demo:

let navItems = document.querySelectorAll('.changeColor');
navItems.forEach(item => {
  item.addEventListener("click", (e) => {
    navItems.forEach(otherItem => {
      otherItem.style.color = "#1A1C20";
      otherItem.classList.remove('active');
    });
    e.target.classList.add('active');
    e.target.style.color = "#f0a500";
  });
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">

<ul class="nav nav-tabs nav-fill justify-content-center mt-3" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor active" id="mathematics-tab" data-toggle="tab" href="#Mathematics" role="tab" aria-controls="Mathematics" aria-selected="true">Mathematics</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="english-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">English</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="verbal-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Verbal</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link changeColor black-text-start" id="nonverbal-tab" data-toggle="tab" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Nonverbal</a>
  </li>
</ul>

This is my solution to your problem

let navItem = document.querySelectorAll('.changeColor');
function someFunction({ target }) {
  navItem.forEach((element) => {
    element.style.color = '#1A1C20';
    element.classList.remove('active');
  });
  target.style.color = '#f0a500';
  target.classList.toggle('active');
}
navItem.forEach((element) => {
  element.addEventListener('click', (e) => someFunction(e));
});
Related