Sam
Sam

Reputation: 45

How to write this simple javascript or jquery?

I have some nav links like so:

<ul id="nav">
   <li><a href="index.html">Home</a>
   <li><a href="about.html">About</a>
   <li><a href="contact.html">Contact</a>
</ul>

How can I add a CSS class called active to the opening <li> tag of the list item that contains the a href whose value matches the current url?

For example, if the current page the user is on is about.html then the nav should look like this:

<ul id="nav">
   <li><a href="index.html">Home</a>
   <li class="active"><a href="about.html">About</a>
   <li><a href="contact.html">Contact</a>
</ul>

Please note:

the urls can have additional parameters like:

about.html?foo=bar&bar=loo

so whatever is used to detect the url should not take parameters into consideration but just the page name and extensions.

I would prefer to achieve this in plain JavaScipt since I am not using jQuery for anything else on the site, but either is fine.

Edit

The index page had index.html in the url when it's landed on from another page but if the domain is types it shows as:

http://www.sitename.com/

so if no page is specified the active class should be attached to the home list's tag.

Upvotes: 3

Views: 905

Answers (3)

mplungjan
mplungjan

Reputation: 177965

Simple version

window.onload=function() {
  var activeLi;
  if (location.pathname) { 
    var fileName = location.pathname.substring(pathname.lastIndexof('/')+1);
  /* just take the start - 
     not handling filenames that are substrings of other filenames 
     nor filenames with more than one dot. */
    fileName = fileName.split('.')[0]; 
    var links = document.getElementById('nav').getElementsByTagName('a');
    for (var i=0;i<links.length;i++) {
      if (links[i].href.indexOf(fileName)==0) { // starts with filename
        activeLi = links[i].parentNode;
        break; 
      }
    }
  }
  else { // no page given
    activeLi = document.getElementById('nav').getElementsByTagName('li')[0];
  }
  if (activeLi) activeLi.className="active";
}

More complex would be to ADD the active to className, but if you do not have other classes on the LI, then it is not needed - but if you use jQuery it is much simpler.

Upvotes: 1

Ravikiran
Ravikiran

Reputation: 1448


//Get sub-domain url 
var currentUrl = window.location.href,
    splitUrlArr = currentUrl.replace(/\?.*/,'').split('\/');
    subDomainUrl = splitUrlArr[splitUrlArr.length-1];
//if url matches the site home url, add classname 'active' to first li
if(splitUrlArr.join('\/') == currentUrl) {
    document.getElementById('nav').getElementsByTagName('li')[0].className = "active";
}else {
    //Find the matching href and add className 'active' to its parent li
    var targetLi = null;
    var links = document.getElementById('nav').getElementsByTagName('a');
    for (var i=0; i < links.length; i++) {
        if (links[i].href === subDomainUrl) { 
            targetLi = links[i].parentNode;
            break; 
        }
    }
    if(targetLi) { targetLi.className = "active"; }
}

Upvotes: 0

Felix Kling
Felix Kling

Reputation: 816462

jQuery:

if(window.location.pathname === '') {
     $('#nav li:first-child').addClass('active');
}
else {
    var path = window.location.pathname;
    path = path.substr(path.lastIndexOf('/') + 1);
    $('#nav li').filter(function(index) {            
        return path === $(this).children('a').attr('href');
    }).addClass('active');
}

Plain JavaScript:

var menu_elements = document.getElementById('nav').children;
if(window.location.pathname === '') {
     menu_elements[0].className += ' active';
}
else {
    var path = window.location.pathname;
    path = path.substr(path.lastIndexOf('/') + 1);
    for(var i = menu_elements.length; i--;) {
        var element = menu_elements[i];
        var a = element.children[0];
        if(a.href === path) {
            element.className += ' active';
            break;
        }
    }
}

Note: children[] is not supported by FF 3.0. If you experience any problems with children, you can substitute this with an appropriate getElementsByTagName call.

Upvotes: 4

Related Questions