Make Internal Links Scroll Smoothly with JavaScript
Pages: 1, 2, 3, 4, 5, 6
We know what we clicked, and what that points to. Now, all we need to know is our location within the document, and what our destination is. This is where Andy Clover's notes are invaluable. First, we find the position of the destination link:
var destx = destinationLink.offsetLeft;
var desty = destinationLink.offsetTop;
var thisNode = destinationLink;
while (thisNode.offsetParent &&
(thisNode.offsetParent != document.body)) {
thisNode = thisNode.offsetParent;
destx += thisNode.offsetLeft;
desty += thisNode.offsetTop;
}
Note that we loop through offsetParents until we get to the document body, as IE requires. Next, we work out where we are currently located:
function getCurrentYPos() {
if (document.body && document.body.scrollTop)
return document.body.scrollTop;
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
if (window.pageYOffset)
return window.pageYOffset;
return 0;
}
IE5 and 5.5 store the current position in document.body.scrollTop, IE6 in document.documentElement.scrollTop, and Netscape-class browsers in window.pageYOffset. Phew!
The way we handle the scrolling is to use setInterval(); this very useful function sets up a repeating timer that fires a function of our choice. In this case, we'll have our function move the browser's position one step closer to the destination; setInterval() will call our function repeatedly and, when we reach the destination, we'll cancel the timer.
First, use clearInterval() to turn off any timers that are currently running:
clearInterval(ss.INTERVAL);
ss.INTERVAL is a variable in which we will later store the ouput of setInterval(). Next, we must work out how big each step should be:
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.STEPS is defined in the script to be the number of steps we take from target to destination. Our "scroll one step" function is called ss.scrollWindow and takes three parameters:
- The distance to scroll.
- The destination position.
- The destination link itself.
We need to construct a call to this in a string, and pass that string to setInterval, along with the frequency with which we want the call repeated:
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
Notice how we're building up a string that's a call to ss.scrollWindow(), rather than just calling ss.scrollWindow() directly. This is one of the most confusing things about setInterval().
Once we've done that, we have to stop the browser from taking its normal course by obeying the link and jumping directly to the destination. Again, this process occurs differently in different browsers. To stop the browser handling this event normally in Internet Explorer, use the following code:
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
Notice the check for window.event, which ensures that we're using IE.
To do the same in Netscape-class browsers, use this code:
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}



