Whenever one builds a website, one issue is always guaranteed time consuming: highlighting the current page or section in the website with a different style.
In theory, this is relatively simple, just add a .current class to the link in question.
So, if you have a menu styled from a list, you’d have:
<ul> <li><a href="#">Link 1</a></li> <li><a class=".current" href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> <li><a href="#">Link 4</a></li> </ul> |
The limitation of this method becomes obvious if you have a site with more than 5-7 pages; each page needs to have its own menu, which makes updates difficult, especially if you prefer to keep the menu in a template.
I’ve seen several solutions to this problem, but I didn’t really like any of them – so I propose something more clever.
A pure CSS solution
One possibility, used by A List Apart would be to assign an id to each link, so that the links above become:
<ul> <li><a id="link1" href="#";>Link 1</a></li> <li><a id="link2" href="#" class=".current">Link 2</a></li> <li><a id="link3" href="#">Link 3</a></li> <li><a id="link4" href="#">Link 4</a></li> </ul> |
Then, you’d have to set the class property for each <body> tag, i.e. <body class="link1">. In the stylesheet definition, you’d write
.link1 a#link1, .link2 a#link2 { background-color: #EEEEEE; |
If you’re relatively new to CSS, the above definition means that any link with id set to link1 that is a descendent of a tag (<body>) with the class .link1 will be “highlighted”.
This method is an improvement in that the menu can be written only once; however, you still have to set the class for the body tag in each page.
Generating HTML
Another solution would be to use PHP/ASPX or any other server language to generate the pages and menu items. Of course, this provides complete freedom, since you can generate the html code any way you like. Still, this method can’t be used in all circumstances. Not all sites require a server technology and making a site dynamic just for this feature would be overkill.
Javascript + CSS
I’m a little surprised that I haven’t seen a similar solution published anywhere, so I’ve thought about sharing it.
The concept is very simple: The javascript code gets the current URL. It then cycles to all links that are contained in the navigation bar (any tag with id="navbar"). If the link points to the same page (i.e. “link1.html"), the code applies a class to the link.
The code should work in all browsers that support getElementById() including IE5, Firefox & Opera. You may add compatibility for older versions of IE by using document.all in addition to document.getElementById()
Here’s the code (rewritten on Oct.11.2007):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | function extractPageName(hrefString) { var arr = hrefString.split('/'); return (arr.length < 2) ? hrefString : arr[arr.length-2].toLowerCase() + arr[arr.length-1].toLowerCase(); } function setActiveMenu(arr, crtPage) { for (var i=0; i < arr.length; i++) { if(extractPageName(arr[i].href) == crtPage) { if (arr[i].parentNode.tagName != "DIV") { arr[i].className = "current"; arr[i].parentNode.className = "current"; } } } } function setPage() { hrefString = document.location.href ? document.location.href : document.location; if (document.getElementById("nav") !=null ) setActiveMenu(document.getElementById("nav").getElementsByTagName("a"), extractPageName(hrefString)); } |
The ony thing left to do is to call setPage() from the html page, just after the menu, with <script language="javascript">setPage()< /script>
You can make the script run without explicitly calling setPage() from the html body, by adding
1 2 3 4 | window.onload=function() { setPage(); } |
in the .js file (Suggested by Alice). If you go this route, please test to make sure that it doesn't interfere with other onLoad events. Also, in this case the effect will be applied only after all page elements have been loaded.
That's all. You can download a fully working example.
Highlighter (4.9 KiB, 15,731 hits)
great solution very helpful! good work, thanks
works awesome – with a little custom tailoring, it did exactly what I needed.
kudos and thanks!
I use this script frecuently in many different brands of content management systems. Always works right away. Congratulations to the developer.
Thanks Armand, I will try the .current method and if it doesn’t work I will use the javascript method.
Have a good day!
thnx brother its work…
Nice little script. Needs a couple of mods referring to how to get the parent LI to highlight even if it’s a child of that li. …I’m working on it and will post in due course.
This is exactly what I am looking for…thank you.
Perfect.
Simple script, but I was amazed at how many variations there were. I liked yours the best.
thank u very much for giving such a simple script. it has reduced my headachae…..
I would like to know how to turn this page into cakePHP.
I mean how to apply this code in cakePHP frame work. i’ m new in cakePHP.
help please..