Reputation: 45
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.
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
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
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
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