Home > Highlighting Hard Coded Active Links with jQuery

Highlighting Hard Coded Active Links with jQuery

When using Drupal's menu system for linking pages on your site the corresponding menu link gets the CSS class active when the referred page is being displayed. To make use of this to improve a site's usability you can highlight this link by assigning a different color, background color, etc. Drupal's l() function also takes care to add the active class to currently displayed links.

On this site I have to blocks in the sidebar (Recommended Articles, Drupal Modules) with hard-coded links to internal pages using plain HTML. My main reason not to use menu items is because I am too lazy and I don't use the l() function to not increase the number of database queries more than necessary.

Since I want to highlight active links, I decided to use JavaScript, which has drawbacks too, the most obvious is it doesn't work when JavaScript is disabled. The HTML of the Drupal Modules block looks as follows:

<ul class="hard-coded">
<li><a href="/tools/cms/drupal/modules/auctionads" title="AuctionAds Drupal Module">AuctionAds</a> - Add eBay ads to your site</li>
...
</ul>

The ul element has the CSS class hard-coded and the value of an href attribute of a link is an absolute path. To test whether the current page corresponds to a link in these sidebar blocks I added the following code snippets to my theme:

In the page.tpl.php file I added these lines to make the base URL available to JavaScript code as the variable base_url and to include the JavaScript file:

<script type="text/javascript">
  <?php print "var base_url = '$base_url';" ?>
</script>
<script src="<?php print $theme_path; ?>/js/seo.js" type="text/javascript"></script>

The next step was to add the following function to the theme's JavaScript file:

if (Drupal.jsEnabled) {
  $(document).ready(function(){
    highlight_active_sidebar_links();
  });
}

function highlight_active_sidebar_links() {
  $("#sidebar ul.hard-coded a").each(function(){
    var current_href = $(this).attr("href");
    if (!$.browser.msie) {
      current_href = base_url + current_href;
    }
    if (document.location == current_href) {
      $(this).addClass("active");
    }
  });
}

The function tests for every link in the sidebar that is contained in an unordered list with the class hard-coded whether the value of the href attribute is the current document's location. If that's the case the CSS class active is added to the anchor element.

When the page is viewed with Internet Explorer the base path is not concatenated to the href attribute, because IE returns the absolute URL when calling $(this).attr("href"). Actually, I don't know why and hope that someone will enlighten my by explaining this in a comment.

I'm not sure why IE returns the absolute path, but it's actually quite useful (if you could do that in other browsers as well). Anyway, if you want IE to return the relative href path, use: this.getAttribute('href',2);
Thanks for the info Dave!
Hi, you forgot to consider the eventual query string, here's my version of the function
function highlight_active_sidebar_links() {
    $("#sidebar ul.hard-coded a").each(function(){
        var href = this.getAttribute('href',2);

        var location = new String( document.location );
        location = location.substr(0, href.length );

        if ( location == href) {
            $(this).addClass("active");
        }
    });
}


PS: you should also check how works the code formatting in your comments engine ;-P
Thanks for the hint and your enhanced code snippet

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <br> <img> <h2> <h3> <h4> <h5>

More information about formatting options

Loading