Building Dynamic Navigation Using JavaScript and jQuery

Ok, I’ll admit, I’m pretty new to JavaScript and jQuery, so as a disclaimer, my coding may not be perfect or concise. With that said, I’m going to explain how to build dynamic navigation highlighting using a little JavaScript and jQuery. The first step is to explain the problem.

Most web sites that follow good usability practices will tell visitors where they are on the site. It’s kind of like that directory map in a shopping mall with the big red “YOU ARE HERE” arrow. On web sites, this is usually accomplished by highlighting or shading the navigation object that the user is currently on.

js-dynamic-nav-highlighting-example

If you’re running a web site on a content management system like WordPress, this is easy to handle. For example, WordPress gives you a class called “current_page_item” that is only added to the list item of the page the user is currently looking at. Pretty useful.

Unfortunately, if you’re not running a web site in a content management system with that level of sophistication, then you’re out of luck. The only way to really implement something like it is to manually build the navigation.

However, JavaScript can help automate most of that. We can use JavaScript and jQuery to dynamically determine what page the user is currently browsing and add a class to the navigation object to highlight it. In the example above, the <a href> tag surrounding “About” has a class of “on” applied to it.

The code:

<script type="text/javascript">
var blog = "blog";
var url = blog;
var siteurl;
var locmatch;

url = url.split(/[s,]+/i);
siteurl = String(location.href);
for (var x = 0; x < url.length; x++) {
  locmatch = siteurl.match(url[ x ]);
}

$(document).ready(function(){
  if (locmatch == blog) {
    $("#page_nav li a[href*='blog']").addClass("on");
  }
  else {
    $("#page_nav li").find("a[href='"+window.location.pathname+"']").each(function(){
      $(this).addClass("on")
    });
  };
});
</script>

The code is broken into two parts consisting of regular JavaScript and then jQuery. The approach behind this script is simple. We want to determine what page a user is currently on and then analyze the <a href> links in the navigation to see if there’s a match. If there is, we’ll apply class=”on” to the matched navigation object.

Furthermore, say for example there is a blog on the web site in question. With a blog, each post would create a new page and that page location would no longer match the navigation object (e.g. “Blog” in the navigation would have a URL of http://www.mysite.com/blog/, but if a user is on a specific post, that URL would change to something like http://www.mysite.com/blog/this-is-a-post/. The URL then would no longer match the <a href> link of the “Blog” navigation object and thus no match would be detected.)

Let’s walk through the code one chunk at a time.

var blog = "blog";
var url = blog;
var siteurl;
var locmatch;

url = url.split(/[s,]+/i);
siteurl = String(location.href);
for (var x = 0; x < url.length; x++) {
  locmatch = siteurl.match(url[ x ]);
}

This chunk of code is designed to look for the word “blog” in the URL path. The blog variable is defining what word to look for (in this case “blog”) and it then stores it in the url variable. The siteurl variable will contain the full path of the current page URL and the locmatch variable will contain a match to “blog” if there is one. The url variable is then split and run through a loop to detect a match of “blog.” The result is stored in the locmatch variable.

The second chunk of code is the jQuery and it does most of the heavy lifting.

$(document).ready(function(){
  if (locmatch == blog) {
    $("#page_nav li a[href*='blog']").addClass("on");
  }
  else {
    $("#page_nav li").find("a[href='"+window.location.pathname+"']").each(function(){
      $(this).addClass("on")
    });
  };
});

Once the document is ready, the first order of business is to determine whether or not the locmatch variable matches the blog variable we defined earlier. If it does, then we instruct the code to find all <a href> tags within the navigation area (anything that is a descendant of #page_nav li) that contains the word “blog” and apply a class of “on.”

If locmatch does not equal the blog variable, the if statement moves to the second part. First, we tell the code to look under #page_nav li and to find any <a href> tags that contain the current page path that the user is on (keep in mind, the code is only looking at the path of the page and not the host, so http://www.mydomain.com would be ignored… this is in case you’re using relative paths). It processes each of the <a href> tags and applies the “on” class to any matches.

So, let’s look at the net result of our efforts. Say we have our navigation/page setup like the following:

<ul id="page_nav">
  <li><a href="/about-me/">About Me</a></li>
  <li><a href="/services/">What I Do</a></li>
  <li><a href="/blog/">My Blog</a></li>
</ul>
<p><a href="/blog/archives/">Check out my blog archives, too!</a></p>

If a user clicks on either “About Me” or “What I Do,” a class called “on” will be applied to the <a href> tag. If the user clicks either “My Blog” or the paragraph link beneath the navigation, the “on” class will be applied to the <a href> tag surrounding “My Blog” in the navigation.

Is there an easier way of doing this? Probably. But like I said, I’m not an expert in JavaScript or jQuery — but I am an expert in what works and this does. Tested in Firefox, Safari, IE6 and IE7 without issue. Let me know if you have any problems.

Have a question or comment about this post? Drop me a line!