[SPIP] +2.1.12
[velocampus/web/www.git] / www / squelettes / javascript / smoothscroll.js
1 // JavaScript Document
2 /* Smooth scrolling
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.
6
7 sil, http://www.kryogenix.org/
8
9 v1.0 2003-11-11
10 v1.1 2005-06-16 wrap it up in an object
11 */
12
13 var ss = {
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
26 // event handler
27 ss.addEvent(lnk,'click',ss.smoothScroll);
28 }
29 }
30 },
31
32 smoothScroll: function(e) {
33 // This is an event handler; get the clicked on element,
34 // in a cross-browser fashion
35 if (window.event) {
36 target = window.event.srcElement;
37 } else if (e) {
38 target = e.target;
39 } else return;
40
41 // Make sure that the target is an element, not a text node
42 // within an element
43 if (target.nodeName.toLowerCase() != 'a') {
44 target = target.parentNode;
45 }
46
47 // Paranoia; check this is an A tag
48 if (target.nodeName.toLowerCase() != 'a') return;
49
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;
60 break;
61 }
62 }
63
64 // If we didn't find a destination, give up and let the browser do
65 // its thing
66 if (!destinationLink) return true;
67
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;
77 }
78
79 // Stop any current scrolling
80 clearInterval(ss.INTERVAL);
81
82 cypos = ss.getCurrentYPos();
83
84 ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
85 ss.INTERVAL =
86 setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
87
88 // And stop the actual click happening
89 if (window.event) {
90 window.event.cancelBubble = true;
91 window.event.returnValue = false;
92 }
93 if (e && e.preventDefault && e.stopPropagation) {
94 e.preventDefault();
95 e.stopPropagation();
96 }
97 },
98
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;
114 }
115 },
116
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;
124 return 0;
125 },
126
127 addEvent: function(elm, evType, fn, useCapture) {
128 // addEvent and removeEvent
129 // cross-browser event handling for IE5+, NS6 and Mozilla
130 // By Scott Andrew
131 if (elm.addEventListener){
132 elm.addEventListener(evType, fn, useCapture);
133 return true;
134 } else if (elm.attachEvent){
135 var r = elm.attachEvent("on"+evType, fn);
136 return r;
137 } else {
138 alert("Handler could not be removed");
139 }
140 }
141 }
142
143 ss.STEPS = 25;
144
145 ss.addEvent(window,"load",ss.fixAllLinks);