OK. So, I’m wrapping up a development. I’ve implemented a smooth scroll script based on the ‘a’ tag. I don’t have time to work another script, so I’m looking for a solution that would allow me to use mine, but replace the ‘a’ tag with something that could allow me to use this effect based only on the menu. I’ve tried replacing with get class and the functionality seemed to die, but maybe I implemented it wrong.
Below is the JavaScript I’m using:
/* Smooth scrolling
Changes links that link to other parts of this page to scroll
smoothly to those links rather than jump to them directly, which
can be a little disorienting.
sil, http://www.kryogenix.org/
v1.0 2003-11-11
v1.1 2005-06-16 wrap it up in an object
*/
var ss = {
fixAllLinks: function() {
// Get a list of all links in the page
var allLinks = document.getElementsByTagName('a');
// Walk through the list
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)) {
// If the link is internal to the page (begins in #)
// then attach the smoothScroll function as an onclick
// event handler
ss.addEvent(lnk,'click',ss.smoothScroll);
}
}
},
smoothScroll: function(e) {
// This is an event handler; get the clicked on element,
// in a cross-browser fashion
if (window.event) {
target = window.event.srcElement;
} else if (e) {
target = e.target;
} else return;
// Make sure that the target is an element, not a text node
// within an element
if (target.nodeName.toLowerCase() != 'a') {
target = target.parentNode;
}
// Paranoia; check this is an A tag
if (target.nodeName.toLowerCase() != 'a') return;
// Find the <a name> tag corresponding to this href
// First strip off the hash (first character)
anchor = target.hash.substr(1);
// Now loop all A tags until we find one with that name
var allLinks = document.getElementsByTagName('a');
var destinationLink = null;
for (var i=0;i<allLinks.length;i++) {
var lnk = allLinks[i];
if (lnk.name && (lnk.name == anchor)) {
destinationLink = lnk;
break;
}
}
if (!destinationLink) destinationLink = document.getElementById(anchor);
// If we didn't find a destination, give up and let the browser do
// its thing
if (!destinationLink) return true;
// Find the destination's position
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;
}
// Stop any current scrolling
clearInterval(ss.INTERVAL);
cypos = ss.getCurrentYPos();
ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
// And stop the actual click happening
if (window.event) {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
if (e && e.preventDefault && e.stopPropagation) {
e.preventDefault();
e.stopPropagation();
}
},
scrollWindow: function(scramount,dest,anchor) {
wascypos = ss.getCurrentYPos();
isAbove = (wascypos < dest);
window.scrollTo(0,wascypos + scramount);
iscypos = ss.getCurrentYPos();
isAboveNow = (iscypos < dest);
if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
// if we've just scrolled past the destination, or
// we haven't moved from the last scroll (i.e., we're at the
// bottom of the page) then scroll exactly to the link
window.scrollTo(0,dest);
// cancel the repeating timer
clearInterval(ss.INTERVAL);
// and jump to the link directly so the URL's right
location.hash = anchor;
}
},
getCurrentYPos: function() {
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;
},
addEvent: function(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;
} else {
alert("Handler could not be removed");
}
}
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);
Note: I’ve tried replacing the ‘get by tag’ line with: “var allLinks = document.getElementsByClassName('mainnav');
An example of the corresponding mark ups is;
<li class='mainnav'><a style="margin-left:3px;" href="#topReception" onMouseOver = "if (document.images) document.top.src= 'http://soniahsieh.com/dev/_images/top-hover.png';" onMouseOut = "if (document.images) document.top.src= 'http://soniahsieh.com/dev/_images/top.png';"><img src="/dev/_images/top.png" name="top" border=0></a></li>
BUT, the script dies with this change. What am I doing wrong?
UPDATE, trying jQuery.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$("a.mainnav").each(function() { // go through all links
var href = $(this).attr("href");
if (href.match(/^#/)) { // if href starts with #
$(this).click(function() { // add a click event to it
var name = $(this).attr("href").substring(1); // get the anchor link
// on click, scroll to the a with a name attribute matching the anchor
$('html, body').animate({ scrollTop: $("a[name='" + name + "']").offset().top }, 1000);
});
}
});
</script>
Corresponding;
<li class='mainnav'><a style="margin-left:3px;" name="topReception" href="#topReception" onMouseOver = "if (document.images) document.top.src= 'http://soniahsieh.com/dev/_images/top-hover.png';" onMouseOut = "if (document.images) document.top.src= '/dev/_images/top.png';"><img src="coolimage/top.png" border=0></a></li>
I know Javascript libraries are sometimes overkill, but you could do this much easier using jQuery and avoid having to deal with all the cross-browser issues yourself: