15.02.2009
SmoothScroll for jQuery
back to overview 7 Comments by Bogdan
A short while ago I realized that jQuery, in comparison to MooTools, does not have a SmoothScroll class that allows “smooth” scrolling within a page, from one anchor to the next. I also could not find any plugins on jquery.com. Thanks to Google I found a few sites that deal with the topic and have thus created my own jQuery SmoothScroll script from different sources:
jQuery SmoothScroll
// jQuery SmoothScroll | Version 10-04-30
$('a[href*=#]').click(function() {
// duration in ms
var duration=1000;
// easing values: swing | linear
var easing='swing';
// get / set parameters
var newHash=this.hash;
var target=$(this.hash).offset().top;
var oldLocation=window.location.href.replace(window.location.hash, '');
var newLocation=this;
// make sure it's the same location
if(oldLocation+newHash==newLocation)
{
// animate to target and set the hash to the window.location after the animation
$('html:not(:animated),body:not(:animated)').animate({ scrollTop: target }, duration, easing, function() {
// add new hash to the browser location
window.location.href=newLocation;
});
// cancel default click action
return false;
}
});
Have fun!
—






Write a comment
7 Comments
Will
19.07.2010 22:02:00
Actually, I hadn’t realized that #Name is valid for *either* of the following syntaxes:
<body id="top">
<a name="top">
e.g. var target = $(this.hash + ", a[name=’" + this.hash.slice(1) + "’]");
So, actually, the script would be improved if both were supported! :)
Bogdan visit website
11.07.2010 12:25:13
Hi Will,
thanks for you feedback! Actually the navigation is between one anchor tag to an arbitrary tag that has the matching id attribute. Like on this blog page when you click on "jump to top" the matching element is <body id="top">. Or in other words, you don’t need a second anchor tag with a name attribute.
Best,
Bogdan
Will
10.07.2010 01:51:09
BTW, changing the following line fixes the issue I mention in my previous comment.
From:
var target=$(this.hash).offset().top;
To:
var target=$("a[name=" + this.hash.substring(1) + "]").offset().top;
Will
10.07.2010 01:38:47
I think the logic is a bit incorrect if you are trying to navigate between one anchor tag to another *named* anchor tag, which is how <a href="#Blah">…</a> works by default. It tries to find something like: <a name="Blah"></a> in the DOM rather than <div id="Blah">…</div>.
It would be nice if both worked, but right now your script always assumes the latter case.
Ahrengot visit website
24.02.2010 09:56:20
Hey! Thank you for this!
I am, however, a complete javascript newbie. Could you elaborate on how to implement this, please?
Bogdan visit website
02.11.2009 17:48:54
Hey Alexei,
thanks for taking a closer look at my jQuery SmoothScroll script!
I took some time to simplify and improve the script. Point 1 should be resolved now.
As for point two: I don’t think it is the job of such a script to determine wether http://www.example.com/index.php would deliver the same page as http://www.example.com/. I think in this case the web developer needs to make sure not to mix both variants in the links of a website first of all.
Alexei
02.11.2009 15:29:24
Hey! Thanks for the snippet!
There are at least 2 cases when it fails:
1. When this.href == http://www.example.com/?id=123#foo
2. When this.href == http://www.example.com/index.php?id=123#foo and location is http://www.example.com/?id=123 (and vice-versa)
For the first one, I added && location.search == this.search to test if the query strings match.
Unfortunately, the second situation is a bit trickier, if not impossible, since the directory index can be anything.