Alex Temper
Alex Temper

Reputation: 23

If the URL contains VALUE add class to link + ROOT

I would like to add an active link to my navigation depending on the url using vanilla JS.

My navigation looks like this:

 <div id="navi">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/contact">Contact</a></li>
 </ul>
</div>

JS looks like this:

function Activelink() {
 link = document.getElementById('navi').getElementsByTagName('a');
 for(i=0; i<link.length; i++) {
    if(document.location.href.indexOf(link[i].href) != -1) {
     link[i].className='active';}
 }}
window.onload = Activelink;

Works well, especially as it also adds the class "active" to the blog link even if a blog post is accessed. Only issue is that <a href="/">Home</a> permanently get's the class "active" assigned as well. Is there a way to avoid this, so that the home link class is only "active" if the homepage is accessed?

Upvotes: 2

Views: 249

Answers (2)

Johannes Stadler
Johannes Stadler

Reputation: 787

First of all, welcome to stack overflow! The answer depends a bit on your future concept of the site and if you will have URLs that are not in your navigation. For example, if you have some kind of copyright page accessible at /copyright linked in the footer but not in your navigation, what should be highlighted then? The Home entry? No entry? Furthermore I assume /blog and /contact can also have subpages? Like /blog/what-ever?

So regardless of the corner cases in the future, a simple solution would be to reverse the for-loop and add a break to the if clause: (Note I changed /blog to /js, because that is part of the URL this test snippet runs in.)

function activeLink() {
    link = document.getElementById('navi').getElementsByTagName('a');
    for(i = link.length - 1; i >= 0; i--) {
       if(document.location.href.indexOf(link[i].href) != -1) {
           link[i].className='active';
           break;
    }
}}
window.onload = activeLink;
a.active{
   background-color:red;
}
 <div id="navi">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/js">Blog</a></li>
    <li><a href="/contact">Contact</a></li>
 </ul>
</div>

Now your for loop checks if window.location.href contains /contact, then if it matches the break would skip all further executions of your loop. Otherwise it will search for /blog and only if none of the first two executions matches it would pick /, as that will always be part of the URL. Hope this helps!

Upvotes: 1

FZs
FZs

Reputation: 18619

You can use endsWith instead of indexOf:

function Activelink() {
 link = document.getElementById('navi').getElementsByTagName('a');
 for(i=0; i<link.length; i++) {
    if(document.location.href.endsWith(link[i].href)) {
     link[i].className='active';}
 }}
window.onload = Activelink;

Upvotes: 1

Related Questions