cris
cris

Reputation: 225

highlighting an active tab with vanilla JS

I am creating a tabbed navigation bar wherein when the tab is active it should change its color the color that i set it to change with. Navigating thru the pages with the tabs works fine however the color highlight on the active tab just don't seem to work.

here is my code so far:

HTML:

<section class="tab" id="active_Current_Tabs">
      <header>Active/Current Tabs</header>
      <nav class="navbar">
        <ul>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem7')">TAB1</li>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem8')">TAB2</li>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem9')">TAB3</li>
        </ul>
      </nav>
      <main class="main-doc">
        <article class="selectedPage" id='lorem7'>
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
        <article class="selectedPage" id="lorem8">
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
        <article class="selectedPage" id="lorem9">
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
      </main>
    </section>

CSS:

article {
  text-align: center;
  width: 100%;
  height: 300px;
  max-height: 300px;
  margin: 0;
}

/*navbar css*/

nav {
width: 100%;
height: 75px;
padding: 0;
margin: 0;
}

nav ul {
  height: 100%;
  padding: 0;
  display: flex;
  list-style: none;
  justify-content: space-around;
}

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 100%;
  height: 100%;
  background-color: #8b9d98;
  cursor: pointer;
  font-weight: 500;
}

.btn:hover {
  background-color: #d7e0e0;
  font-weight: 700;
  transition: .5s;
}

/*main css*/
main {
  margin-top: 0;
}


/*Active/Current Tab */

#lorem7 {
  display: flex;
  flex-direction: column;
  background-color: #49c2a4;
  align-items: center;
  justify-content: center;
}

#lorem8 {
  display: none;
  flex-direction: column;
  background-color:#35386f;
  align-items: center;
  justify-content: center;
}

#lorem9 {
  display: none;
  flex-direction: column;
  background-color:#e28968;
  align-items: center;
  justify-content: center;
}

Javascript:

// active/current tab function

function activeTab(evnt, currPage) {
  var currenttab;
  var pages = document.getElementsByClassName('selectedPage');
  for (i = 0; i < pages.length; i++) {
    pages[i].style.display = "none";
  }
  //for dehighlighting inactive tabs
  currenttab = document.getElementsByClassName('currentTab');
  for(j = 0; j < currenttab.length; j++) {
    currenttab[j].className = currenttab[j].className.replace("green", " ");
  }
  document.getElementById(currPage).style.display = "flex";
  evnt.currentTarget.className += "green"; //this appends the color to active tab
}

help please! T_T

Upvotes: 2

Views: 3000

Answers (3)

Sunday Cletus
Sunday Cletus

Reputation: 13

To create a tabbed navigation bar wherein when the tab is active it should change its color to a custom color that you have set. You could use this few lines of vanilla JavaScript.

JS:

var activeTab;
var acctOptions = document
  .querySelector(".account-options")
  .querySelectorAll("li");
acctOptions.forEach(option => {
  option.addEventListener("click", function() {
    if (activeTab) activeTab.classList.remove("active");
    activeTab = option;
    activeTab.classList.add("active");
  });
});

CSS:

.active {
  background: blue;
}

HTML:

<ul class="account-options">
   <li class='login'><a>Login</a></li>
   <li class='register'><a href="register.html">Register</a></li>
   <li class='account' ><a>My Account</a></li>
   <li class='reward-points'><a>Reward Points</a></li>
   <li class='password-reset'><a>Reset Password</a></li>
   <li class='logout'><a>Logout</a></li>
</ul>

Upvotes: 0

jstein
jstein

Reputation: 81

I'm not sure what you were trying to do with the "green" class because there were no rules for it in your CSS. I answered the question assuming you wanted the active tab to be the same color as the active page. Sorry if that's not what you intended, but I think it makes sense.

To avoid problems with specific class names, you can use .classList methods like "add" and "remove". This way you don't have to worry about the order of class names in the markup. Examples:

tabs[i].classList.remove('active')
e.currentTarget.classList.add('active')

You can also attach your event listener (click handler) dynamically to keep your HTML uncluttered. Example:

for(j = 0; j < tabs.length; j++) {
    // attach event listener to all tabs
    tabs[j].addEventListener('click', clickTab)
}

You can also make your CSS less repetitive by assigning similar styles to a common class:

.page {display:none;}
.page.active {
    display:flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

I modified your IDs in order to be able to reference tabs and pages independently without explicitly passing parameters to the click handler functions. Example:

<li id="t2" class="tab">TAB2</li>
...
<article class="page" id="p2">...</article>

Here is my JS Bin:

http://jsbin.com/defidih/edit?html,css,js,console,output

Upvotes: 1

Shilly
Shilly

Reputation: 8589

evnt.currentTarget.className += "green";

This line will add to the already existing className.

So your class class="btn currentTab" becomes class="btn currentTabgreen" instead of class="btn currentTab green" if you didn't add green to it before. So it would better to use currenttab[j].className.replace("green", ""); to reset the previous green classes and evnt.currentTarget.className += " green"; to set the new green class.

Edit: this does imply that the classname will keep growing with one space every time. SO the optimal would be to use classList.add() and classList.remove() instead of manually editting the class string.

function activeTab(evnt, currPage) {
  var currenttab;
  var pages = document.getElementsByClassName('selectedPage');
  for (i = 0; i < pages.length; i++) {
    pages[i].style.display = "none";
  }
  //for dehighlighting inactive tabs
  currenttab = document.getElementsByClassName('currentTab');
  for(j = 0; j < currenttab.length; j++) {
    currenttab[j].className = currenttab[j].className.replace("green", "");
  }
  document.getElementById(currPage).style.display = "flex";
  evnt.currentTarget.className += " green"; //this appends the color to active tab
}
article {
  text-align: center;
  width: 100%;
  height: 300px;
  max-height: 300px;
  margin: 0;
}

/*navbar css*/

nav {
width: 100%;
height: 75px;
padding: 0;
margin: 0;
}

nav ul {
  height: 100%;
  padding: 0;
  display: flex;
  list-style: none;
  justify-content: space-around;
}

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 100%;
  height: 100%;
  background-color: #8b9d98;
  cursor: pointer;
  font-weight: 500;
}

.btn:hover {
  background-color: #d7e0e0;
  font-weight: 700;
  transition: .5s;
}

/*main css*/
main {
  margin-top: 0;
}


/*Active/Current Tab */

#lorem7 {
  display: flex;
  flex-direction: column;
  background-color: #49c2a4;
  align-items: center;
  justify-content: center;
}

#lorem8 {
  display: none;
  flex-direction: column;
  background-color:#35386f;
  align-items: center;
  justify-content: center;
}

#lorem9 {
  display: none;
  flex-direction: column;
  background-color:#e28968;
  align-items: center;
  justify-content: center;
}
.green {
  background-color: green;
}
<section class="tab" id="active_Current_Tabs">
      <header>Active/Current Tabs</header>
      <nav class="navbar">
        <ul>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem7')">TAB1</li>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem8')">TAB2</li>
          <li class="btn currentTab" onclick="activeTab(event, 'lorem9')">TAB3</li>
        </ul>
      </nav>
      <main class="main-doc">
        <article class="selectedPage" id='lorem7'>
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
        <article class="selectedPage" id="lorem8">
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
        <article class="selectedPage" id="lorem9">
          <h2>Lorem</h2>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, est?</p>
        </article>
      </main>
    </section>

Upvotes: 1

Related Questions