Bookmark this on Delicious Share this on Facebook Share this on Twitter

Smooth Anchors jQuery Plugin

Posted on July 30, 2009 at 9:46 pm / By Ian / In Javascript
Tags: , , , , ,

Links which use the pound(#) symbol to anchor to another area of the page are generally used for navigating large blocks of text. This plugin creates a simple animation for anchor links by quickly scrolling the page to the area where the anchor is at rather than just jumping right to the anchor like normal.

Setup

Simple include the smooth anchors plugin, along with the jQuery file to the <head> section of your page.

1
2
<script language="javascript" src="js/jquery-1.3.2.js"></script>
<script language="javascript" src="js/jquery.smoothanchors.js"></script>

Then initialize the smooth anchors by specifying, in the header, the speed at which the page should scroll when an anchor link is clicked.

1
2
3
4
5
<script>
$(document).ready(function(){
	$.smoothAnchors("normal");
});
</script>

Simply create anchors and links on the page like normal.

1
2
<a href="#sect1">Go to Section 1</a>
<a name="sect1">Section 1</a>

This plugin will also fail elegantly, in the event that a user has javascript turned off or disabled anchor links will resume normal functionality.

Click here to see the demo.

Download the Smooth Anchors plugin.

Limitations

  • Smooth anchors currently only work when an anchor is linked to from the same page that it exists on.
  • Horizontal scrolling is not yet implemented.

Version 2 Now Available

Version two of Smooth Anchors now supports the following features:

  • Vertical and horizontal window scrolling.
  • Easing
  • The ability to turn off the URL redirection.

Usage:

1
$.smoothAnchors(speed, easing, redirect);

speed – A string representing one of the three predefined speeds (”slow”, “normal”, or “fast”) or the number of milliseconds to run the animation (e.g. 1000). (Default “fast”)
easing (Optional) – The name of the easing effect that you want to use (plugin required). There are two built-in values, “linear” and “swing”.
redirect (Optional) – Allow the URL redirect after the scrolling effect has finished. (e.g. “false”)

1
2
3
4
5
<script>
$(document).ready(function(){
	$.smoothAnchors("normal", "swing", false);
});
</script>

Click here to see the demo.

Download the Smooth Anchors plugin.


Responses

  • Auzzie says:

    I’m having a hell of a time getting this to work with a flash nav in AS3.

    The script below obviously sends the page to the anchor, but how do I call the jquery functionality. I’ve never tried to call a javascript from a actionscript so it’s not going so hot.

    var url:String = “http://www.test.com/#anchor”;
    var request:URLRequest = new URLRequest(url);

    mainButton.addEventListener(MouseEvent.CLICK,buttonClick);

    function buttonClick(e:MouseEvent):void{
    navigateToURL(request, ‘_self’);
    }

    Any help?

    • Ian says:

      Good question, my script alone cant do it but if you include your jquery file and add this to the portion of your page it should allow you to do what you need to do.

      function scrollTo(url, speed, easing, redirect){

      url = url || “#”;
      speed = speed || “fast”;
      easing = easing || null;
      redirect = (redirect === true || redirect == null) ? true : false;

      if(url){

      if(url.indexOf(”#”) != -1){

      var aParts = url.split(”#”,2);
      var anchor = $(”a[name='"+aParts[1]+”‘]”);

      if(anchor){

      if($(document).height()-anchor.offset().top >= $(window).height()
      || anchor.offset().top > $(window).height()
      || $(document).width()-anchor.offset().left >= $(window).width()
      || anchor.offset().left > $(window).width()){

      $(’html, body’).animate({
      scrollTop: anchor.offset().top,
      scrollLeft: anchor.offset().left
      }, speed, easing, function(){

      if(redirect){
      window.location = url
      }

      });

      }

      return false;

      }

      }

      }

      }

      Within your AS code you should be able to just call the javascript function directly…. I believe thats how Flash works.


      function buttonClick(e:MouseEvent):void{
      scrollTo('#anchor');
      }

      It should give you the same functionality so youll still be able to change the easing and speed without any problems.

      • Auzzie says:

        Thanks so much Ian.

        Your function worked perfectly. The only difference for the AS was in AS3 the way you communicate events/parameters to the HTML framework is with the ExternalInterface class. So the click tag ended up looking like this:

        import flash.external.ExternalInterface;

        function buttonClick(event:MouseEvent):void {
        ExternalInterface.call(”scrollTo”,”#execution”);
        }

        And it works great, thanks again.

        Auzzie

  • Seán says:

    Are there any examples of horizontal scrolling in use? Also is it possible to utilise both horizontal and vertical scrolling—does it scroll diagonally or does it scroll horizontally first and then vertically?
    Thanks
    Sean

  • Stan says:

    Works fine on FF3.5.5 and Safari 4.0.3. In Opera it works quirky.
    It didn’t work when I used the type attribute instead of the language attribute, any idea why?
    very cool effect i have to say.

    • Ian says:

      What do you mean the type and language attributes?

      I mostly only support FF, IE, and Safari — but my guess as to why it doesn’t work in Chrome and Opera might have something to do with the html/body.scrollTop/scrollLeft functions. They probably have some other name for it. Or maybe those browsers process links differently in that it’s firing the actual link before the onclick event.

  • valerio says:

    doesnt work on safari and chrome. is there a way to make it work?

    • Ian says:

      well, no not as far as I know but I intentionally added a graceful failure in that if the script doesn’t work it will just revert to the browser default for those types of links.

  • mike says:

    Is there anyway to call this function from inside a flash file?
    Im making a site with a flash menu and would love to have it work with smoothanchors2. at the moment I have my buttons in flash call a java function written in my html :

    AS2 flash call -> HTML

    on(release) {
    getURL(”javascript:topgo()”);
    }

    Java code within the HTML =

    function topgo() {
    window.location.href=”#topanchor”
    }

    this is making my anchors work as instant links. I have tried including the smoothscroll2 files and coding in the html alon side this etc, but it is not being called. I have a feeling I need to combine the smoothscroll function with the anchor script I have used (as above) but have no idea how I would do this… if anyone has any ideas please reply!

    • mike says:

      anyone help please? im a jquery noob =[

      • Ian says:

        function scrollTo(url, speed, easing, redirect){

        url = url || “#”;
        speed = speed || “fast”;
        easing = easing || null;
        redirect = (redirect === true || redirect == null) ? true : false;

        if(url){

        if(url.indexOf(”#”) != -1){

        var aParts = url.split(”#”,2);
        var anchor = $(”a[name='"+aParts[1]+”‘]”);

        if(anchor){

        if($(document).height()-anchor.offset().top >= $(window).height()
        || anchor.offset().top > $(window).height()
        || $(document).width()-anchor.offset().left >= $(window).width()
        || anchor.offset().left > $(window).width()){

        $(’html, body’).animate({
        scrollTop: anchor.offset().top,
        scrollLeft: anchor.offset().left
        }, speed, easing, function(){
        if(redirect){
        window.location = url
        }
        });

        }

        return false;

        }

        }

        }

        }

        That should work for you. Simply call the function like this
        onclick=”scrollTo(’#test’,1000)”

        Then place your “test” anchor in the document wherever you need it.

        • Ian says:

          Youll also want to include the jQuery framework in your document.

          • mike says:

            thanks Ian, how do i call it from flash though? at the moment i have:

            1. a command in the flash file that calls a named java function in the html
            2. seperate named functions for each of the anchors

            what i need is to make those seperate named fuctions perform individual scrolls to the asigned anchor.

            I apreciate your help but I dont see how I use it =[

    • rich says:

      You can use the ExternalInterface in actionscript to talk to the javascript functions in your browser.

      http://kb2.adobe.com/cps/156/tn_15683.html

      –Rich

  • mark says:

    Ok now I know why, a jquery.dimension.js file which I use in my tooltip is not compatible with this anchor jquery plugin. I deleted it in my header and the tooltip works fine and same with the smooth anchor plugin.

    I don’t know what that file is for but it sure gets in the way of the smoothanchor. With that deleted, the two works just fine. thanks for this man!

  • Mark says:

    My anchors won’t work when going up. But it works really fine when going down? I’m sure I got all the required things to do. What suppose to be the problem? Please help. thanks…

  • Jeff says:

    huuummm I like it !!

  • Bret says:

    Ian,

    I was wondering how can I make this work on external pages. where it goes to the new page and animates to the #?

    Thanks again for you awesome plug in!

    • Ian says:

      lol good question. I’m not quite sure how to do that yet but if I figure it out it’ll definitely show up in the next release.

  • i use it on our site selling cheap new cars http://www.buyacar.co.uk/cars/new_cars.jhtml and it works great. I agree with comment that it leaves user felling like they have not left the page. It also gives them opportunity to see what they missed as page scroll slowly.

  • John Goodwin says:

    I’ve been using this effect for a while on my own site: http://www.getnorthern.co.uk.

    As for Warren’s ‘wasting time’: “I am sick of having my browsing time wasted by all these gimmicky effects that are used simply because they make the web designer feel powerful.” – I suggest you disable all scripts, images etc, or use a text-only browser if your time is quite so precious.

    However, used well, such effects can improve usability and the user experience. A scrolled page, using this effect, shows the user that they are still on the same page, and can help give them a sense of orientation.

  • Helen says:

    Velocity works perfectly when you replace “slow” (including the quotation marks) by milliseconds. 3-5000ms is a good value if you have rich ancor navigation inside a long document and want the user to know what is happening: “Okay, it’s moving from here to there.”

  • Helen says:

    What the problem is: The url won’t be rewritten. It stays …html/#top.

    • Ian says:

      Hmm, what browser are you using? It should be rewriting after is scrolls the body.

      • Helen says:

        Ian, it’s happening in all browsers. I have a “Scroll to the top” at the end of the page. When I click, everything works fine, but it changes the uri from page.html to page.html#top.

        It’s a pity because the script I usually used only knows scrolling to #top. I wanted to use SmoothAncors because it scrolls to every ancor which is nice when you have rich navigation inside a long page. But it is difficult for the user at that moment he wants to navigate back to the page before that page.

        The advantage of the script is that it is very lightweight in comparison with all scrolltop scripts I have seen before. In Opera, it does not work at all like all scrolltop-scripts (don’t know why), but here it doen’t mind because it is the only one that does not make the page flickering.

        Finally, this script can be a very good script if the uri-rewrite can be finxed.

        • Ian says:

          Ok, I see what you’re saying. I’ll make sure to add that option in the next version. Quick fix would be to comment out or remove the line in jquery.smoothanchors.js that says “window.location = url;” which should stop that from happening.

          I put that in there because I wanted the anchors to behave like normal anchors(with scrolling) and I wanted to allow people to bookmark them, but like I said I’ll give the option to enable or disable that. Thanks for the input!

          • Ben says:

            If he would script the hack conditionally he could have it both ways..
            I can’t be bothered getting the syntax right now or looking up your variables, but something like:
            if(!anchor = #top) “window.location = url;”;

        • Ben says:

          Actually, silly me. I had to fix this today, and naturally I just had to remove the condition blocking full links.
          So:
          // if(url.indexOf(”#”) != -1 && url.indexOf(”#”) == 0){
          became:
          // if(url.indexOf(”#”) != -1){

          I also changed the attribute from name to id (since name is being depreceated):
          // var anchor = $(”a[id='"+aParts[1]+”‘]”);

  • warren says:

    This makes me laugh. Windows and Linux users look at OS X and say it’s “so slow” because the interface doesn’t “snap”. They’re complaining about the time spent executing all the subtle window effects. Here you are taking something that performs it job very nicely and deliberately slowing it down, and in the case of these longer scrolls making it very hard on the eyes. Easing?!?! Even more time wasting nonsense? I am sick of having my browsing time wasted by all these gimmicky effects that are used simply because they make the web designer feel powerful. It seems hypocritical and even cynical to worry about such thing as how long it takes to download the page content if you’re writing things that deliberately waste time. Are you javascript developers trying to reclaim the crown as the most odious abusers of unintelligently overused web technology? Are you so upset that the Flash crowd had stolen it that you will stop at nothing to get it back?

    • Ian says:

      I never thought OSX was “slow” and I was a full blown Windows user – actually I think things like that add to the appeal of a Mac. I understand completely what you’re saying though, some things are just over used and it’s just annoying(hence why I typically don’t use them), but some “time wasting nonsense” can be really elegant. It can also add to the usability of a page if done right. I’m a firm believer that form and function go hand in hand.

      Either way, if your browsing time is so precious then why did you waste so much of it commenting on this? lol

    • Seth says:

      wow, your an epic failure. the web is turning into a rich environment for web applications and not just web sites these days. if you really think that javascript development is such a waste of time, then don’t use the internet because every web site you use, uses javascript. and your comment about flash is ridiculous; first of all, flash is a plugin for the web browser, aka, you first need to install the plugin and second you have more processing time due to it being a plugin. javascript is built into every modern web browser and can do everything flash can with a little imagination and it doesnt requires some dumb plugin.

      go back to walmart and sell more spongebob underwear you small brained chimp

  • Very simple to use. How do you slow the speed and can you ease in or out at all?

    • Ian says:

      You can set the speed using an interval in milliseconds or with “slow”, “normal”, or “fast”.

      As far as easing, I don’t currently have that setup, but I can add that to the to-do list for version 2.

  • Ian says:

    no problem… I believe that with flash you would do something like

    on(release) {
    scrollTo(”#anchor”,1000);
    }

    The first parameter “#anchor” being whatever the name of the anchor(s) are within your page, and the second being the speed in milliseconds. I’m pretty sure you can do that with Flash, calling javascript functions outside of the Flash document.

Post a Comment

Name:
Email:
Website: