3 Changes links that link to other parts of this page to scroll
4 smoothly to those links rather than jump to them directly, which
5 can be a little disorienting.
7 sil, http://www.kryogenix.org/
10 v1.1 2005-06-16 wrap it up in an object
14 fixAllLinks: function() {
15 // Get a list of all links in the page
16 var allLinks
= document
.getElementsByTagName('a');
17 // Walk through the list
18 for (var i
=0;i
<allLinks
.length
;i
++) {
19 var lnk
= allLinks
[i
];
20 if ((lnk
.href
&& lnk
.href
.indexOf('#') != -1) &&
21 ( (lnk
.pathname
== location
.pathname
) ||
22 ('/'+lnk
.pathname
== location
.pathname
) ) &&
23 (lnk
.search
== location
.search
)) {
24 // If the link is internal to the page (begins in #)
25 // then attach the smoothScroll function as an onclick
27 ss
.addEvent(lnk
,'click',ss
.smoothScroll
);
32 smoothScroll: function(e
) {
33 // This is an event handler; get the clicked on element,
34 // in a cross-browser fashion
36 target
= window
.event
.srcElement
;
41 // Make sure that the target is an element, not a text node
43 if (target
.nodeName
.toLowerCase() != 'a') {
44 target
= target
.parentNode
;
47 // Paranoia; check this is an A tag
48 if (target
.nodeName
.toLowerCase() != 'a') return;
50 // Find the <a name> tag corresponding to this href
51 // First strip off the hash (first character)
52 anchor
= target
.hash
.substr(1);
53 // Now loop all A tags until we find one with that name
54 var allLinks
= document
.getElementsByTagName('a');
55 var destinationLink
= null;
56 for (var i
=0;i
<allLinks
.length
;i
++) {
57 var lnk
= allLinks
[i
];
58 if (lnk
.name
&& (lnk
.name
== anchor
)) {
59 destinationLink
= lnk
;
64 // If we didn't find a destination, give up and let the browser do
66 if (!destinationLink
) return true;
68 // Find the destination's position
69 var destx
= destinationLink
.offsetLeft
;
70 var desty
= destinationLink
.offsetTop
;
71 var thisNode
= destinationLink
;
72 while (thisNode
.offsetParent
&&
73 (thisNode
.offsetParent
!= document
.body
)) {
74 thisNode
= thisNode
.offsetParent
;
75 destx
+= thisNode
.offsetLeft
;
76 desty
+= thisNode
.offsetTop
;
79 // Stop any current scrolling
80 clearInterval(ss
.INTERVAL
);
82 cypos
= ss
.getCurrentYPos();
84 ss_stepsize
= parseInt((desty
-cypos
)/ss
.STEPS
);
86 setInterval('ss.scrollWindow('+ss_stepsize
+','+desty
+',"'+anchor
+'")',10);
88 // And stop the actual click happening
90 window
.event
.cancelBubble
= true;
91 window
.event
.returnValue
= false;
93 if (e
&& e
.preventDefault
&& e
.stopPropagation
) {
99 scrollWindow: function(scramount
,dest
,anchor
) {
100 wascypos
= ss
.getCurrentYPos();
101 isAbove
= (wascypos
< dest
);
102 window
.scrollTo(0,wascypos
+ scramount
);
103 iscypos
= ss
.getCurrentYPos();
104 isAboveNow
= (iscypos
< dest
);
105 if ((isAbove
!= isAboveNow
) || (wascypos
== iscypos
)) {
106 // if we've just scrolled past the destination, or
107 // we haven't moved from the last scroll (i.e., we're at the
108 // bottom of the page) then scroll exactly to the link
109 window
.scrollTo(0,dest
);
110 // cancel the repeating timer
111 clearInterval(ss
.INTERVAL
);
112 // and jump to the link directly so the URL's right
113 location
.hash
= anchor
;
117 getCurrentYPos: function() {
118 if (document
.body
&& document
.body
.scrollTop
)
119 return document
.body
.scrollTop
;
120 if (document
.documentElement
&& document
.documentElement
.scrollTop
)
121 return document
.documentElement
.scrollTop
;
122 if (window
.pageYOffset
)
123 return window
.pageYOffset
;
127 addEvent: function(elm
, evType
, fn
, useCapture
) {
128 // addEvent and removeEvent
129 // cross-browser event handling for IE5+, NS6 and Mozilla
131 if (elm
.addEventListener
){
132 elm
.addEventListener(evType
, fn
, useCapture
);
134 } else if (elm
.attachEvent
){
135 var r
= elm
.attachEvent("on"+evType
, fn
);
138 alert("Handler could not be removed");
145 ss
.addEvent(window
,"load",ss
.fixAllLinks
);