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?

David97
  • 31
  • 7

4 Answers4

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>
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
  • 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: https://www.youtube.com/watch?v=g3uFtVgaHU4&feature=youtu.be – David97 Nov 23 '20 at 13:19
  • 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? – Lawrence Cherone Nov 23 '20 at 13:56
  • 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: https://codepen.io/pen/ZEOgyNN – David97 Nov 23 '20 at 14:30
  • 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 https://stackoverflow.com/questions/1034621/get-the-current-url-with-javascript (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` – Lawrence Cherone Nov 23 '20 at 14:36
  • Got it to work with `location.href` . Thank you so much! – David97 Nov 23 '20 at 15:38
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>
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!

Zia Ahmad
  • 150
  • 8
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>
David97
  • 31
  • 7