Anchor-based URL navigation with jQuery

Update: I've since written a anchor-based URL navigation plugin that attempts to capture what's described below. -- I'm working on an application that has several panels of content, each accessed by clicking on a link in the page's main navigation. I wanted to give users the ability to get back to a panel after they'd left the application, without having to click on the panel in the navigation again, so I set it up so the URL would include an anchor link indicating the current panel (e.g. http://www.mysite.com/index.html#panel1). This had the added benefit of encouraging me to be a good front-end developer by following the principles of progressive enhancement -- before I set this up, a user without Javascript wouldn't get anywhere when they clicked on a link in the page's main navigation, and that's no good. Now, users without Javascript will be taken down the page to the panel they want, and users with Javascript will get the fancy Web 2.0 panels that show and hide and fade and stuff. Here's what I did:

  • Set up anchor tags at the top of each "panel" div, and give the anchor tags a class of anchor:
    ...
  • Put links to the anchors in the main navigation:
    1. Panel 1
    2. ...
  • Set up the onclick behavior for the main navigation items:
    var j = 1;
    $('ol#nav li').each(function() {
      $(this).click(function() {
        $('ol#nav li').removeClass('current');
        $(this).addClass('current');
        $('div.panel:visible').hide();
        $('#panel'+j).fadeIn(500);
      });
      j++;
    });
    
    // don't include return false! you want the URL 
    // to change to reflect which panel is showing --
    // the next step will make it so that all of the anchors
    // will be at the top of the page, so the fact that this
    // returns true won't cause the page to scroll to the anchor.
  • Move all the anchor tags to the top of the page so users with Javascript won't get bumped down the page when they click on a link:
    $('a.anchor').remove().prependTo('body');
    You might not want to include this step, or you might want to move the anchor tags elsewhere. This worked for me in this case, though.
  • When a user arrives on the page, look to see if they've requested a specific panel:
    var myFile = document.location.toString();
    if (myFile.match('#')) { // the URL contains an anchor
      // click the navigation item corresponding to the anchor
      var myAnchor = '#' + myFile.split('#')[1];
      $('ol#nav li a[href="' + myAnchor + '"]').parent().click();
    } else {
      // click the first navigation item
      $('ol#nav li:first').click();
    }
The end. Now users who arrive via a URL that includes an anchor tag will go to the proper panel, and everyone else will get the default behavior of going to the first panel.

Loading mentions Retweet

14 comments

Dec 24, 2007
rdmey | Anchor-based URL navigation, Take 2 said...
[...] noticed I was getting a lot of visits via Google for my post on anchor-based URL navigation with jQuery, so I decided to write a plugin that would accomplish the same [...]
Feb 21, 2008
Quiller said...
Good tip! jQuery is great for little tricks like this. I would, however, suggest using trigger() to simulate an event. It's more cross-browser friendly and ensures the binding is called. Some time, somewhere, this will save you a few hours of troubleshooting!
Feb 27, 2008
Ariel Flesler said...
Hi Rebecca
Have you checked jQuery.LocalScroll ?
http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html

Cheers

Apr 21, 2008
links for 2008-04-22 « Mike Does Tech said...
[...] rdmey | Anchor-based URL navigation with jQuery (tags: jquery programming ajax navigation) [...]
Aug 31, 2008
摘錄若干 jQuery 連結 said...
[...] Anchor-Based URL navigation with jQuery 使用錨點 1:觀念講解 [...]
Nov 11, 2008
The Rollsteady Network » Blog Archive » links for 2008-11-11 said...
[...] Anchor-based URL navigation with jQuery | rdmey (tags: javascript jquery web) « MmmMm doughnuts [...]
Jan 31, 2009
James said...
nice tip! got the idea and solve my problem :)

thanks

Aug 27, 2009
tehpage said...
I thought we can't trigger an anchor?
Nov 25, 2009
Di said...
It's good, but not SEO-friendly at all.

I think the better solution will be pre-poccessing URI by PHP or other you may use server-side language.

Jan 14, 2010
RC said...
Hello Rebecca,

Thank you for this code. Would this work with accordion menus? I have a page with jquery accordions (http://www.keene.edu/grants/fdg.cfm). I'd like to be able to link to a specific bit of content within one of these menus and, when the user arrives there, have the menu expand. I can get to a specific menu *heading* using the name attribute, but can't get the menu to expand just yet.

Thanks again!
RC

Apr 09, 2010
Joan said...
You guys should have a look: http://www.quirksmode.org/dom/events/tests/hashchange.html
Jun 18, 2010
Esteban said...
Why not use location.hash instead of var myFile = document.location.toString();?

Nice article. Thanks!

Jun 21, 2010
Bugsy said...
Thanks so much for this! Provides the solution to a lot of things I've been wanting to do. A lot simpler than I thought it would be.
Jul 17, 2010
Lucas, Miami Web Design said...
I have being working on adding anchor text links to all my pages and connecting all my pages among themselves. I hope this increases my rankings at Google. I also have added one way links.

Leave a comment...