jQuery a better idea to add active class to menu item
This simple script adds an "active" class to a link in a list when page's url is = link's href attribute
var TheP = window.location.pathname.split('/');
var HeRe = TheP[TheP.length-1];
$('ul a').each(function(){
var Link = $(this).attr('href');
if (Link == HeRe){ $(this).addClass('active');}
});
And it works. But ... only when the href attribute is just a single file href="index.html"
. Doesn't work at all in these next cases or similar:
<a href="foo/index.html">foo</a>
<a href="../bar/index.html">bar</a>
Actually to solve it I could write:
var TheP = window.location.pathname.split('/');
var P1 = TheP[TheP.length-1];
var P2 = TheP[TheP.length-2];
var HeRe = P2+"/"+P1;
$('ul a').each(function(){
var Ln = $(this).attr('href');
var Ln = Ln.split('/');
var L1 开发者_开发百科= Ln[Ln.length-1];
var L2 = Ln[Ln.length-2];
var Link = L2+"/"+L1;
if (Link == HeRe){$(this).addClass('active');}
});
But ... ehm ... I think there should be a better and more flexible way. Also because what is above doesn't work having just a single file as path : (
Update: I misunderstood the question originally. Re-reading it, it sounds like you want to be sure not to match all index.html
s, but only the specific one you're in (which makes rather more sense, actually).
In that case, you can do this:
var path = window.location.href; // Just grabbing a handy reference to it
$('ul a').each(function() {
if (this.href === path) {
$(this).addClass('active');
}
});
...because the href
property (which is not the same as the "href" attribute) of the DOM element is the absolute path.
Live example
Obviously, the more you can do to constrain that initial selector (within reason), the better. For instance, if this is all within some navigation structure, only working within that structure will be more efficient.
Also, if there will be a lot of matches, you can avoid doing the jQuery wrapper when adding the class if you like:
if (this.href === path) {
this.className += " active"; // note the space
}
Original answer:
If the href
attributes will always have a /
before the filename part, then:
var TheP = window.location.pathname.split('/');
var HeRe = TheP[TheP.length-1];
$('ul a[href$="/' + HeRe + '"]').addClass('active');
That uses an attribute ends-with selector to find the relevant links.
If the href
attributes may sometimes be simply index.html
or similar, you can do this:
var TheP = window.location.pathname.split('/');
var HeRe = TheP[TheP.length-1];
$('ul a[href$="/' + HeRe + '"], ul a[href="' + HeRe + '"]').addClass('active');
...which will catch the ones with /
in front of them using the "ends-with" selector, and also the ones where there's an exact match using the "equals" selector.
Rather than break up the pathname why don't you just compare the whole thing. If you have relative urls it should be easy. Also, you can perform a replace to deal with absolute urls.
var mainpart = window.location.protocol + "//" + window.location.host;
var path = '/' + window.location.pathname;
$('ul a').each(function(){
var Link = $(this).attr('href').replace(mainpart, '');
if (Link === path || '/' + Link === path){ $(this).addClass('active');}
});
var TheP = window.location.pathname.split('/');
var HeRe = TheP[TheP.length-1];
$('ul a[href$="' + HeRe + '"]').addClass('active');
According to specification http://www.w3.org/TR/css3-selectors/#attribute-substrings :
Three additional attribute selectors are provided for matching substrings in the value of an attribute:
- [att^=val] Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
- [att$=val] Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.
- [att*=val] Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything.
精彩评论