1

I want to add .active class to <a> tag depending on which page I'm currently on, so I can style it.

When I go to Home page, this should happen:
<li><a class="active" href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">LOCATION</a></li>

When I go to About page, then this should happen:
<li><a href="#">HOME</a></li>
<li><a class="active" href="#">ABOUT</a></li>
<li><a href="#">LOCATION</a></li>

Etcetra...

This image describes what I'm trying to achieve:

enter image description here

const currentLocation = location.href;

const menuItem = document.querySelectorAll('a');

const menuLength = menuItem.length

for (let i = 0; i<menuLength; i++){
if(menuitem[i].href === currentLocation){

menuItem[i].className = "active"
}
}
ul li a {

color: black;
background-color: silver;
}

ul li a.active {

color: white;
background-color: black;
}
<nav class="navbar">
   <div class="navbar-links">
      <ul>
         <li><a href="http://example.com/home/">HOME</a></li>
         <li><a href="http://example.com/about/">ABOUT</a></li>
         <li><a href="http://example.com/location/">LOCATION</a></li>
      </ul>
   </div>
</nav>

It just doesn't work. Any suggestions?

1
  • The href of every link is just # while window.location contains the full address. Commented Nov 23, 2020 at 0:29

4 Answers 4

1

Target only the .navbar-links a then loop over each one, in the loop do 2 things:

  • Check if current hash or path equals the links href attribute.
  • Add an event handler to the link to set the class, and before setting it, loop over the others to remove the current (not needed if you're not using a hash).

const menuItem = document.querySelectorAll('.navbar-links a');

menuItem.forEach(el => {
  // current
  if (el.getAttribute('href') === (location.hash || '#home')) {
    el.classList.add("active")
  }

  // handle click
  el.addEventListener("click", e => {
    // remove others
    menuItem.forEach(el => el.classList.remove("active"))
    // set active
    e.target.classList.add("active")
  })
})
ul li a {
  color: black;
  background-color: silver;
}

ul li a.active {
  color: white;
  background-color: black;
}
<nav class="navbar">
  <div class="navbar-links">
    <ul>
      <li><a href="#home">HOME</a></li>
      <li><a href="#about">ABOUT</a></li>
      <li><a href="#location">LOCATION</a></li>
    </ul>
  </div>
</nav>

If not using a hash the extra steps are not needed as it will reload the page:

const menuItem = document.querySelectorAll('.navbar-links a');

menuItem.forEach(el => {
  if (el.getAttribute('href') === (location.path || '/home')) {
    el.classList.add("active")
  }
})
ul li a {
  color: black;
  background-color: silver;
}

ul li a.active {
  color: white;
  background-color: black;
}
<nav class="navbar">
  <div class="navbar-links">
    <ul>
      <li><a href="/home">HOME</a></li>
      <li><a href="/about">ABOUT</a></li>
      <li><a href="/location">LOCATION</a></li>
    </ul>
  </div>
</nav>

Sign up to request clarification or add additional context in comments.

5 Comments

Okay, first JS you posted works perfectly UNTIL new page loads(refreshes). I've made a quick video on youtube to show you what I mean: youtube.com/watch?v=g3uFtVgaHU4&feature=youtu.be
you simply need to match what's in href. whats in the href for each link, hash, path, full url or a mix of both?
I actually forgot to meantion that I use only 1 header instance for all pages(I don't have seperate header instances for each page). Here is the code and that I used in the video: codepen.io/pen/ZEOgyNN
I've mentioned it in the answer.. location.path is for /foobar/baz whilst location.hash is for /#foo-bar links, you have to use the correct one for it to match the if statement to apply the active class. see stackoverflow.com/questions/1034621/… (you could use just window.location instead of location.path or location.href) using query params like in your pen would need location.search not location.hash
Got it to work with location.href . Thank you so much!
0

location.href will return the full url.

I think what you want is location.pathname, so if you have something like www.yourdomain.com/home location.pathname would be equals to "/home" while location.href would be equals to www.yourdomain.com/home.

Also, all a tags are pointing to the same '#'.

What you want to do is probably set the href to the path you want.

for ex:

<li><a href="/home">HOME</a></li>

1 Comment

I excluded real links on purpose, I edited my post to re-add them to avoid confusion, sorry.
0

Here is the javascript you can use:

const menuItem = document.querySelectorAll('a');
menuItem.forEach( item => {
    if(item.href===location.href){
    item.classList.add('active')
    return;
  }
})

I used foreach array method to loop through all links. In the if statement, we are confirming if item.href (href attribute of a tag) is equal to current url you are on, if that is true, it will add class of active to that link and return.

Not sure if that's what u wanted i am also a beginner!

Comments

0

This solved my problem:

const menuItem = document.querySelectorAll('.navbar-links a');

menuItem.forEach(el => {
  // current
  if (el.getAttribute('href') === (location.href || 'http://example.com/home/')) {
    el.classList.add("active")
  }

  // handle click
  el.addEventListener("click", e => {
    // remove others
    menuItem.forEach(el => el.classList.remove("active"))
    // set active
    e.target.classList.add("active")
  })
})
.navbar-links a {
  color: black;
  background-color: silver;
}

.navbar-links a.active {
  color: white;
  background-color: black;
}
<nav class="navbar">
  <div class="navbar-links">
    <ul>
      <li><a href="http://example.com/home/">HOME</a></li>
      <li><a href="http://example.com/about/">ABOUT</a></li>
      <li><a href="http://example.com/location/">LOCATION</a></li>
    </ul>
  </div>
</nav>

1 Comment

I'm glad I could help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.