Article

Home » Client-side Coding » JavaScript & Ajax Tutorials » Make Internal Links Scroll Smoothly with JavaScript

About the Author

Stuart Langridge

author_slangridge Stuart is an information architect for a law firm in the UK. He writes about JavaScript and DHTML, as well as pretty much anything else that catches his attention, at kryogenix.org. Stuart also maintains Stylish Scripting: SitePoint's DHTML and CSS Blog.

View all articles by Stuart Langridge...

Make Internal Links Scroll Smoothly with JavaScript

By Stuart Langridge

December 15th, 2003

Reader Rating: 7.5

Page: 1 2 3 Next

When they’re navigating through a long document, users often are confused or disoriented when they click a link that jumps to another location in that same document.

Are they on the same page, or a different page? Should they scroll more from here? What's going on?

The answer to this problem is to scroll the user through the document to the linked location, like this. In this tutorial, we'll use a smattering of JavaScript to ensure that links that are internal to the document scroll the user to their destination, rather than jumping straight there and confusing users.

Finding Internal Links

First, we need to identify all the links in the document, and then work out which of them are internal ones. Getting a list of all the links is easy:

 var allLinks = document.getElementsByTagName('a');

We need to walk through this list, and work out which of the links we've found are internal. An internal link will have a hash (#) symbol in it, and it will point to the document we're currently looking at. The useful location object tells us about the URL of the document we're looking at now, so try this:

 for (var i=0;i<allLinks.length;i++) {
 var lnk = allLinks[i];
   if ((lnk.href && lnk.href.indexOf('#') != -1) &&  
       ( (lnk.pathname == location.pathname) ||
   ('/'+lnk.pathname == location.pathname) ) &&  
       (lnk.search == location.search)) {
          DO SOMETHING WITH THE LINK HERE
   }
 }

Here, the for loop walks through the list of links in the document, and we check for three things:

  1. Does the link contain a hash?
    We check this using the link's href property, and the indexOf() function to find the location of one string in another.

  2. Is the link the same as the current location?
    Links (and the location object) have a pathname attribute. The pathname of the URL http://www.sitepoint.com/about/who/mharbottle.php is /about/who/mharbottle.php in some browsers, and about/who/mharbottle.php in others (note the presence or absence of the first slash). We must check for both.

  3. Is the querystring the same as the current location?
    The querystring is everything that appears after the ? in a url; this is obviously important if your site is database driven. JavaScript defines a search attribute on location and links that contain the querystring.

If each of these questions is true, then we know the link is an internal one, and we can set it to scroll to its destination.

Scroll, Don’t Jump!

Now we've identified an internal link, we want to make it scroll when it’s clicked. To do this, we’ll need to attach an onclick event handler to the link. In days of old, when Web developers were bold, many thought (well, I did) that event handlers were set on a link within the HTML:

<a href="http://www.sitepoint.com/" onclick="myEventHandler()">

But this isn't really the truth; instead, you should attach an event listener to the link object. The W3C specifies a standard method to do this, as does Internet Explorer; Scott Andrew has usefully provided a function to handle both:

function ss_addEvent(elm, evType, fn, useCapture)
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
{
 if (elm.addEventListener){
   elm.addEventListener(evType, fn, useCapture);
   return true;
 } else if (elm.attachEvent){
   var r = elm.attachEvent("on"+evType, fn);
   return r;
 }
}

So, in our loop over the links, we call this script to attach a smooth-scroll function to the internal link:

ss_addEvent(lnk,'click',smoothScroll);

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links

Follow SitePoint on...