Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery a better idea to add active class to menu item

Tags:

jquery

url

menu

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 : (

like image 799
Steve Avatar asked Nov 21 '25 07:11

Steve


1 Answers

Update: I misunderstood the question originally. Re-reading it, it sounds like you want to be sure not to match all index.htmls, 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.

like image 149
T.J. Crowder Avatar answered Nov 23 '25 23:11

T.J. Crowder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!