Deutsche Version medianotions.de subscribe RSS feed

15.02.2009

SmoothScroll for jQuery

Tags: JavaScript, jQuery | last edited: 18.04.2013


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

<script type="text/javascript">

   $(document).ready(function()
   {         
      //
      // jQuery SmoothScroll | Version 18-04-2013
      //

      $('a[href*=#]').click(function() {

         // skip SmoothScroll on links inside sliders or scroll boxes also using anchors or if there is a javascript call
         if($(this).parent().hasClass('scrollable_navigation') || $(this).attr('href').indexOf('javascript')>-1) return;

         // duration in ms
         var duration=1000;

         // easing values: swing | linear
         var easing='swing';

         // get / set parameters
         var newHash=this.hash;
         var oldLocation=window.location.href.replace(window.location.hash, '');
         var newLocation=this;

         // make sure it's the same location      
         if(oldLocation+newHash==newLocation)
         {
            // get target
            var target=$(this.hash+', a[name='+this.hash.slice(1)+']').offset().top;

            // adjust target for anchors near the bottom of the page
            if(target > $(document).height()-$(window).height()) target=$(document).height()-$(window).height();         

            // animate to target and set the hash to the window.location after the animation
            $('html, body').animate({ scrollTop: target }, duration, easing, function() {

               // add new hash to the browser location
               window.location.href=newLocation;
            });

            // cancel default click action
            return false;
         }
      });
   });
   
</script>

Have fun!

Downloads


Bookmark or recomend this page

Write a comment


41 Comments

Chips

23.04.2013 11:48:44

Hey mrsam,

Re: Offset

I cobbled this together from some searching, and it seems to work. I have zero idea about jquery, so this was more or less a fluke. These helped -
http://stackoverflow.com/questions/9618997/run-scrolltop-with-offset-of-element-by-id
http://stackoverflow.com/questions/9068587/accounting-for-a-fixed-header-with-animate-scrolltop-and-target-offset-top

I don’t know what the ‘var customoffset’ is doing, but it seems to be required. I’m sure Bogdan could refine it into a much more eloquent solution.

Replace these particular lines in Bogdans script -

// get target
var target=$(this.hash+’, a[name=’+this.hash.slice(1)+’]’).offset().top -20 ;

//change this number to create the additional off set
var customoffset = 20;

// adjust target for anchors near the bottom of the page
if(target > $(document).height()-$(window).height()) target=$(document).height()-$(window).height();

// animate to target and set the hash to the window.location after the animation
$(‘html, body’).animate({scrollTop: target}, duration, easing, customoffset, function() {

Bogdan visit website

18.04.2013 09:45:05

Hi mrsam,

great you found a solution and thank you for the contribution. I tested it in all major browsers and it works great, so I updates the SmoothScroll script.

Thanks,
Bogdan

mrsam

17.04.2013 14:31:57

Hi Bogdan,

Yup it works on this site. Cant quite figure out why, but could naturally be some conflict with other js code on my site - although not throwing any errors.

In my messing around with it I tried doing the following:

Replaced:
$(animationSelector).animate(

With:
$(‘html, body’).animate(

This made the smooth scroll work in Crome - any idea why that could be?

My site got a fixed header block, so I need to offset the target scroll with lets say 100px to take a count of the header block height. Any suggestions on how to do that ?

Bogdan visit website

11.04.2013 11:52:00

Hi mrsa,

Thank you for your feedback! I just testet SmoothScroll on Windows 7 with the latest Chrome an it worked fine.

Do you have the same problems here on this blog page? It uses the same script for scrolling.

Bogdan

mrsa

11.04.2013 00:02:30

Hey Bogdan,

Great work with the scroller! Like others ive been looking for a solid solution with some smooth scrolling and found some to work but would ruin my shadowbox slideshow.

Sadly I couldnt get this to work in the latest version of Crome:
26.0.1410.64 m

This is on a fresh win 7 install. Works fine in Firefox though.
In Crome what I experience is that I click > theres a 1 sec delay > kumps to my anchor, but no smooth scroll

Karl

24.02.2013 11:38:57

Thanks, have been looking for a smooth scroller that works on the iPad and tried a bunch of them - this is the first that I got to work. Great job!

Bogdan visit website

16.01.2013 16:55:43

Hi Nel,

strange, I just tried it in Chrome 24 on Mac and Windows and it works. This blog uses the same script, does it work for you in Chrome?

Bogdan

Nel

16.01.2013 15:23:50

not working on latest version of chrome :(

Nel

16.01.2013 15:01:22

thank you so much! it works so great!

Bogdan visit website

07.01.2013 09:11:55

Hi n2,

The SmoothScroll script works fine on my iOS 6 iPhone. On which iOS-Version do you experience problems?

Bogdan

n2 

03.01.2013 04:56:05

Bodgan
Like everyone else, this is a great script. I was able to get it working on the desktop versions on browsers, but like some, was not able to see what might be causing it to fail on iOS browsers. Any ideas would be appreciate

Thx

Bogdan visit website

26.11.2012 18:28:53

Hallo weschl,

you can simply adapt the if query in line 9 // skip SmoothScroll … to the selector of your tabbed navbar. That’s it :-)

Bogdan

weschl visit website

26.11.2012 12:29:37

hi bogdan,

thank you for this great working snippet.
have a problem on my one page site im working at.
need to exclude some anchors beeing part of another jquery
(its a tabbed navbar on my aboutme section)links are not working anymore since i included yours. how can i exclude #skills #awards…and so on in your js?

thanx alot bro

Bogdan visit website

18.09.2012 10:15:35

Hi Hans,

simply load the SmoothScroll.js file in your main template like this:

<script type="text/javascript" src="PATH-TO-SCRIPT/SmoothScroll.js"></script>

Bogdan

Hans

15.09.2012 14:59:14

Hi,

I can’t get it to work, can you please explain how to install this for example in a magento page? I have only the normal anchor working, but not the smooth one. I have seen on this page that many of you loved it so i want to use this too!

Thank you.

Best regards,

Hans

jonathan visit website

20.06.2012 08:55:05

thank you so much!

Works on my iphone and ipad, and doesn’t look jerky.

I have tried so many of these… and this is finally working!

Thanks again!!!

Mario visit website

14.05.2012 23:00:12

Thank you. This is scrolling made easy.

marie

14.03.2012 14:47:59

Thanks so much! Easy to use! Exactly what I was looking for!

jeff

16.02.2012 22:44:08

Awesome! One that works with Iphone/Ipad! Thanks very much for the great script.

David

17.01.2012 04:05:31

Thank you very much! Works a charm and is very appreciated after trying so many complex, heavy js files already. Regards!!

Erik visit website

19.10.2011 20:10:43

Great! Most of the times I use the smooth scroll script from css-tricks, but that doesn’t seem to work with sticky waypoints. But this one does, and it looks awesome! Thanks, you really made my day :)

Sandy

15.09.2011 08:45:30

THANK YOU! This is perfect. I’ve been searching and searching for a good solid script that does this. Yours works flawlessly. Will be sure to credit you in the source.

Bogdan visit website

02.09.2011 17:37:11

Dear Hannes,

I am glad you like my scroll script, however what you need in the first step is a beginner tutorial for JavaScript to understand how things work.

Bogdan

Hannes

02.09.2011 14:42:07

Hi!
I’m eager to try this!
But I have no what so ever knowledge of javascripts.

How do I implement it on my website?
I imagine that I put the smoothscroll.js file in the root of my website.
Should I link to it in some way?

Where do I put the script then?

Thank you very much!
Looking forward to answers!

Dylan

14.08.2011 05:56:44

Top effort mate. Keep up the good work.

ember

10.08.2011 16:13:33

works like a charm with my wordpress powered theme! thank you so much!

Bogdan visit website

29.07.2011 17:17:19

Strange in my tests the Smothscroll Script works perfect in Chrome 12. Please let me know in which version of Chrome you had the problems.

Bogdan

szmigieldesign visit website

29.07.2011 16:44:25

Hello.

Your script seems to work pretty well. However, I can’t get it to work with Chrome. Do you have any experience on that matter?

neil hanvey visit website

14.06.2011 13:49:31

at last, a working script that doesn’t have a random offset bug. much appreciated for this

Bogdan visit website

08.06.2011 10:29:56

I am glad you like my script Jay. Unfotunately I have no sponsors, it is all sponsored by myself :-)

Jay

08.06.2011 07:10:45

I’ve tried them all and yours is the best. I think I’ll go visit your sponsors now. Thank you.

Davinder visit website

06.05.2011 13:18:10

this is simplest and awesome, thank you so much

Kars

23.04.2011 12:23:15

Simplicity FTW! I had to search a bit before I found this. I’m not an expert on JS so this was really easy to use. Thank you

Ashton visit website

09.04.2011 07:11:13

Freaking finally. I’ve had such trouble finding simple jQuery for scrolling to an anchor. Everything was over-bloated; but mostly just didn’t work. Simple ftw. Thanks

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.