Animated anchor links with unobtrusive javascript

Posted on September 30, 2005

In a previous post I suggested that linking to anchors within a page could be a usability enhancement.

I've now implemented this idea using unobtusive javascript. The script parses all of the links to anchors on the page and replaces them with a javascript method that scrolls the page to the anchor instead of jumping to it. Additionally, the script checks whether the target is above or below the link, and adds an arrow to indicate the direction using css & background images. Turning off javascript leaves you with classic anchor links. I like.



Comments (24)

thomas said

strange, i've just implemented this on a website yesterday, but still have usability issues. How do you manage to keep the regular html anchors (#s), while using javascript to animate ?
FYI the page in question is http://www.weareclandestine.com/design/index.html

Posted by: thomas at September 30, 2005 02:33 PM .

timg said

@thomas: the links to the anchors (href="#anchor") are set to "#" by the script:

anchors[i].href = "#";

Posted by: timg at September 30, 2005 02:52 PM .

thomas said

Speaking of accessibility and granted i'm using Movable Type, i was thinking about adding an anchor made of the title of the entry in my case so that the final url would be .../index.html#my_entry_title instead of obscure /index.html#000043.

Posted by: thomas at September 30, 2005 03:00 PM .

mattiz said

WOW!! blingbling...*

Posted by: mattiz at September 30, 2005 10:12 PM .

barry said

bravo tim.

Posted by: barry at October 1, 2005 06:25 PM .

Sebastian Becker said

This is a nice effect, very similar to this one ...

Tutorial:
Sitepoint

Demo:
Kryogenix

... but cooler (arrows) ,easier implemented and may be less obstrusive (?).

But there is a little flaw: Scrolling always starts at the top, which can be a little annoying, especially if there is only a short distance to scroll at the end of a long page.

In this case scrolling looks annything but smooth, it's more like a flash!

Thanks for your great work anyways, and if the manchined issue would be fixed, this script would be one off my all time JavaScript gimmick favourites!

Regards, Sebastian

Posted by: Sebastian Becker at February 2, 2006 09:53 PM .

bsn said

@sebastian

Thanks for pointing that out. Doesn't occur in all browsers. Problem fixed by adding a return false; to the JavaScript handler to prevent the href="#" jumping to a non-existent anchor element (ie. top of the page).

With the return false; I don't even have to replace the original href values now...

Posted by: bsn at February 2, 2006 10:23 PM .

Sebastian Becker said

Sorry, but in my main browser (IE 6) scrolling still always starts at the top - but it works better in Firefox. As you said: It's probably a problem of the browser ...

By the way:

I've just stumbled over the cool flashing effect if you click the quote-button. Is it explained anywhere?

The usability of this form could be slightly improved if entries in the "Name" and "Email Address" field would not disappear if one checks "Remember Me: No" ...

Posted by: Sebastian Becker at February 8, 2006 08:12 AM .

bsn said

@sebastian

1. have to look into it, when I have time. I normally write this from home, where I don't have access to Internet Explorer. :)

2. the quote effect is briefly explained here: http://www.brandspankingnew.net/archive/2005/09/comment_quoting.html

3. the form comes from the standard movable type template. I haven't really looked at it that closely. Then again, if you click "don't remember me", you can't complain if it forgets you!

Posted by: bsn at February 8, 2006 09:05 AM .

bsn said

OK. I found out why IE was causing problems (again), and I seemed to have solved it now. It was working in IE 5.5 but not in 6 because Microsoft changed the way you retrieve the current scoll position via the DOM.

http://javascript.about.com/library/bliebug.htm

Posted by: bsn at February 13, 2006 08:51 PM .

luix said

hi,
with a little delay i noticed that wonderful script. i would like to use it, but: how do i remove the prompt:
»scrollTop: 2080« etc?

Posted by: luix at February 15, 2006 10:22 AM .

bsn said

@luix Sorry, the debug output was still in the script. Gone now.

Posted by: bsn at February 15, 2006 10:24 AM .

luix said

bsn said

@luix Sorry, the debug output was still in the script. Gone now.

great! thank you
luix

Posted by: luix at February 15, 2006 12:06 PM .

Wolfgang said

I always get a javascript error in IE 6:
'offsetTop' is null or not an object

Posted by: Wolfgang at May 16, 2006 12:22 PM .

Eric said

Hey there, i tried to plop your great code into something i was doing - but i built the site as a side scroller.. your code works great up and down? what do you suggest?

Posted by: Eric at July 21, 2006 08:49 PM .

th said

Great job!

But I´m working with image-maps and usual links.
Is there a possibility to use the script for both tags?
("a" and "area")

Posted by: th at September 22, 2006 12:02 AM .

bsn said

@th

Theoretically possible, but it requires more than a minute or so of programming to achieve...

Posted by: bsn at September 22, 2006 10:02 AM .

Steve C. said

Hey, I love this script! I wanted to use it for my company's public site, but of course, 90% of our viewers use IE. So I've done some modifications and it works in IE6 now. Feel free to peruse the script at http://www.stevecochrane.com/js/smooth_anchors.js

Here's what I've changed:
1) Improved detection of the window's scroll position, via this handy article: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
2) Included a function called findPosY that acts as offsetTop for IE.
3) Replaced the onmousedown with onclick, because I noticed that Firefox had a tendency to flash to the top before it transitioned down to the anchor. This fixed the issue.
4) Multiplied the duration by 3 for IE since it scrolls about that much faster.
5) Integrated addLoadEvent, now all you have to do is include the js file for the script to run.
6) Removed the line that replaces the hrefs with #, since that is no longer necessary with return false now in there (as you've stated in the comments).

Unfortunately this appears to still have trouble in IE7, because you still have to use document.documentElement, AND they have fixed the faster scrolling thing. So I THINK it scrolls way too slow in IE7, but I'm not sure because I'm just looking at it in Virtual PC and that's always super slow anyway :) If someone could test it in IE7 on a PC and post what it does that'd be great.

Posted by: Steve C. at October 7, 2006 02:54 AM .

Mason P said

Guys...this is great! I love the effect. Thanks for your work and your posts.

Posted by: Mason P at January 18, 2007 09:42 PM .

Jason D said

it looks like you can't get away without having a doctype defined.

Posted by: Jason D at March 13, 2007 05:30 PM .

Paul said

I saved the file to the same directory as the STCVPM.htm file.
I edited STCVPM.htm to have:
|

|
in the Head section It doesn't do what that webpage did. Do I have to code something else to make it work?

Paul

Posted by: Paul at March 14, 2007 08:40 PM .

mike* said

Eric said

Hey there, i tried to plop your great code into something i was doing - but i built the site as a side scroller.. your code works great up and down? what do you suggest?

hey guys.. i'm in the same boat as eric, if anybody knows how to allow scrolling right, left, up and down then please let me know!

cheers.. mike

Posted by: mike* at May 4, 2007 08:00 PM .

mark said

this script works great, but it "breaks" the browser back button (meaning it will not take you back to a previous page, but back to the last position before the anchor).

any suggestions on how to fix this? thanks!

Posted by: mark at July 26, 2007 10:44 PM .

Rob said

Hey, nice script! Its just what I have been after apart from one little thing which I dont think has been mentioned yet. Im using and Image generated by CSS for my Back to Top button. Any chance this can be modified to not use the general anchor but use an ID or Class instead?

Still great work tho! PS (Im a Javascript Nub!)

Posted by: Rob at August 6, 2007 10:30 PM .