views:

8166

answers:

4

I am currently trying to make a navigation-menu where an active-class is applied to the anchors with hrefs that match the current url, so I can style that anchor in a way that makes it stand out from the rest of the menu.

This is my mark-up:

<div id="sidebar">

<h2>Navigation menu</h2>

<h2 class="subnav"><a href="menu1/menu_item1">Menu item 1</a></h2>
<h2 class="subnav"><a href="menu1/menu_item2">Menu item 2</a></h2>
<h2 class="subnav"><a href="menu1/menu_item3">Menu item 3</a></h2>
<h2 class="subnav"><a href="menu1/menu_item4">Menu item 4</a></h2>
<h2 class="subnav"><a href="menu1/menu_item5">Menu item 5</a></h2>

</div>

This is the jQuery:

   jQuery(function($) {

    // get the current url
    var path = location.pathname.substring(1); 

    // defining the top subnav anchor
    var $top_item = $('#sidebar h2:nth-child(2) a'); 

    // defining all subnav anchors
    var $all_items = $('#sidebar h2.subnav a'); 

    // defining the anchors with a href that matches the current url
    var $selected_item = $('#sidebar h2 a[@href$="' + path + '"]'); 

    // setting the selected menu item'class as active
    $selected_item.addClass('active'); 

    // THIS IS WHERE I THINK THE ERROR IS
    // if none of the h2.subnav's has a url that matches 
    // the current location then assume that it's the top one that's active:
    if ($all_items("href") !== path) $top_item.addClass('active');

});

I am applying the active-class with jQuery, it works fine as long as there is a match between an anchors href and the location url. If the url don't match any of the anchors I want the active-class to be applied to the $top_item. That part of my jQuery doesn't work.

I can't see what the error is, but then again I'm somewhat of a Javascipt/jQuery n00b. Any help would be appreciated.

+1  A: 

Give this code a shot, its something I put together for the company that I work for.

// highlight tab function
var path = location.pathname;
var home = "/";
$("a[href='" + [path || home] + "']").parents("li").each(function() { 
 $(this).addClass("selected");
});
jrutter
A: 

I think you can simplify this a bit:

function highlightSelected()
{
  $("h2.subnav a").each(
    function()
    {
      if (location.pathname.indexOf(this.href) > -1)
      {
        $(this).addClass("selected");
      }
    }
  );
}
Tom
+4  A: 

This should do want you want: mark the matching link, and failing that, mark your default one.

function markActiveLink() {

    //Look through all the links in the sidebar
   $("div#sidebar a").filter(function() {

      //Take the current URL and split it into chunks at each slash
      var currentURL = window.location.toString().split("/");

      //return true if the bit after the last slash is the current page name
      return $(this).attr("href") == currentURL[currentURL.length-1];

    //when the filter function is done, you're left with the links that match.
    }).addClass("active");

   //Afterwards, look back through the links. If none of them were marked,
   //mark your default one.
   if($("div#sidebar a").hasClass("active") == false) {
      $("div#sidebar h2:nth-child(2) a").addClass("active");
    }
 }

markActiveLink();

Also, I found an official tutorial on this on the jQuery Docs site - scroll to the bottom to see the jQuery code. It's tighter than mine, although it's not tailored to your situation.

Nathan Long
The first part worked great, just had to adjust it a bit to fit my url-scheme.I can't get the last snippet to work, however. I inspect the source with Firebug it shows that none of the anchors has the "active" class.
timkl
I think my selector syntax on the last line was the problem. I have edited it. Does this work?
Nathan Long
Nice! Thanks for the help :D
timkl
A: 

great read.. but, I have to make a suggestion.. even if the JS works perfectly, you really should keep all menu list items within an Unordered List (or Ordered List),.. as a best practice.. :)