202

I'm looking for a way to include a slide effect for when you click a link to a local anchor either up or down the page.

I'd like something where you have a link like so:

<a href="#nameofdivetc">link text, img etc.</a>

perhaps with a class added so you know you want this link to be a sliding link:

<a href="#nameofdivetc" class="sliding-link">link text, img etc.</a>

Then if this link is clicked, the page slides up or down to the required place (could be a div, heading, top of page etc).


This is what I had previously:

    $(document).ready(function(){
    $(".scroll").click(function(event){
        //prevent the default action for the click event
        event.preventDefault();

        //get the full url - like mysitecom/index.htm#home
        var full_url = this.href;

        //split the url by # and get the anchor target name - home in mysitecom/index.htm#home
        var parts = full_url.split("#");
        var trgt = parts[1];

        //get the top offset of the target anchor
        var target_offset = $("#"+trgt).offset();
        var target_top = target_offset.top;

        //goto that anchor by setting the body scroll top to anchor top
        $('html, body').animate({scrollTop:target_top}, 1500, 'easeInSine');
    });
});
k0pernikus
  • 60,309
  • 67
  • 216
  • 347
ade123
  • 2,773
  • 8
  • 29
  • 32

14 Answers14

461

Description

You can do this using jQuery.offset() and jQuery.animate().

Check out the jsFiddle Demonstration.

Sample

function scrollToAnchor(aid){
    var aTag = $("a[name='"+ aid +"']");
    $('html,body').animate({scrollTop: aTag.offset().top},'slow');
}

scrollToAnchor('id3');

More Information

dknaack
  • 60,192
  • 27
  • 155
  • 202
  • 64
    This can also be made generic to work with all internal anchor links in the page: `$("a[href^=#]").click(function(e) { e.preventDefault(); var dest = $(this).attr('href'); console.log(dest); $('html,body').animate({ scrollTop: $(dest).offset().top }, 'slow'); });` – bardo Nov 02 '14 at 21:32
  • @bardo, how is it supposed to be implemented? I replaced dkmaack's solution with yours, but the sliding is not there (the anchor itself is functional). What am I missing? – jakub Jan 21 '15 at 13:25
  • It should work by default. Just make sure to add it in the usual `$(document).ready()` function, otherwise the events won't attach properly and it won't behave as expected. – bardo Jan 22 '15 at 00:45
  • 2
    @bardo also add `history.pushState(null, null, dest);` as you are preventing the default location hash change – Mike Causer Aug 07 '15 at 04:27
  • 11
    FYI in addition to @bardo's solution, you should escape the hash when using the latest jQuery like so, $("a[href^=\\#]") https://stackoverflow.com/questions/7717527/smooth-scrolling-when-clicking-an-anchor-link/18365991#18365991 – jaegs Oct 06 '17 at 20:09
  • 1
    What's the purpose of animating both html AND body? Looks like a situation where we don't know what we do and just do it all. Might this start multiple scollings? – ygoe Mar 10 '18 at 18:52
  • All the answers here are pretty much using the same solution - animate, scroll top, to offset of the top of the element with the anchor. On Chrome, however, this consistently overscrolls down, and anchored element is out of the view. – Pawel Veselov Oct 01 '19 at 00:17
48

Assuming that your href attribute is linking to a div with the tag id with the same name (as usual), you can use this code:

HTML

<a href="#goto" class="sliding-link">Link to div</a>

<div id="goto">I'm the div</div>

JAVASCRIPT - (Jquery)

$(".sliding-link").click(function(e) {
    e.preventDefault();
    var aid = $(this).attr("href");
    $('html,body').animate({scrollTop: $(aid).offset().top},'slow');
});
cronfy
  • 1,001
  • 1
  • 15
  • 32
santillanix
  • 1,947
  • 18
  • 17
  • 1
    Very simple yet powerful solution, that allows complete control. I think this answer should get more upvotes. – cronfy Feb 17 '17 at 14:44
  • Agreed, this is the best solution and helped me a lot – probablybest Mar 06 '18 at 14:43
  • It works but defeats the purpose of using `name`. When you use ``, you can reference it from outside as well however, your solution does not provide that. – Ramtin Oct 06 '18 at 22:46
13
function scroll_to_anchor(anchor_id){
    var tag = $("#"+anchor_id);
    $('html,body').animate({scrollTop: tag.offset().top},'slow');
}
user2342558
  • 5,567
  • 5
  • 33
  • 54
ipegasus
  • 14,796
  • 9
  • 52
  • 76
  • 3
    Genuine question, does the +"" do anything in the second line? – Rob Apr 21 '16 at 15:07
  • @Rob javascript does not have string interpolation, so using `+` with strings or vars concatenates them, like: `"#some_anchor"`. Really, the second concat `anchor_id + ""` is not needed, I believe. – onebree Sep 26 '16 at 20:25
  • 1
    Thanks @onebree It was the second concat I was wondering about :) – Rob Oct 12 '16 at 09:11
7

This made my life so much easier. You basically put in your elements id tag and its scrolls to it without a lot of code

http://balupton.github.io/jquery-scrollto/

In Javascript

$('#scrollto1').ScrollTo();

In your html

<div id="scroollto1">

Here I am all the way down the page

bobthenob
  • 149
  • 2
  • 2
6

You should also consider that the target has a padding and thus use position instead of offset. You can also account for a potential nav bar you don't want to be overlapping the target.

const $navbar = $('.navbar');

$('a[href^="#"]').on('click', function(e) {
    e.preventDefault();

    const scrollTop =
        $($(this).attr('href')).position().top -
        $navbar.outerHeight();

    $('html, body').animate({ scrollTop });
})
Matthias
  • 737
  • 8
  • 14
  • IMHO the best solution because it doesn't need additional classes and annoying padding math in the css for fixed navbars – KSPR Feb 20 '19 at 08:18
  • But this doesn't rewrite the anchor tag in the url. Add `history.pushState({}, "", this.href);` to keep the url updated – KSPR Feb 20 '19 at 08:51
5

My approach with jQuery to just make all of the embedded anchor links slide instead of jump instantly

It's really similar to the answer by Santi Nunez but it's more reliable.

Support

  • Multi-framework environment.
  • Before the page has finished loading.
<a href="#myid">Go to</a>
<div id="myid"></div>
// Slow scroll with anchors
(function($){
    $(document).on('click', 'a[href^=#]', function(e){
        e.preventDefault();
        var id = $(this).attr('href');
        $('html,body').animate({scrollTop: $(id).offset().top}, 500);
    });
})(jQuery);
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
4

Here is the solution that worked for me. This is a generic function which works for all of the a tags referring to a named a

$("a[href^=#]").on('click', function(event) { 
    event.preventDefault(); 
    var name = $(this).attr('href'); 
    var target = $('a[name="' + name.substring(1) + '"]'); 
    $('html,body').animate({ scrollTop: $(target).offset().top }, 'slow'); 
});

Note 1: Make sure that you use double quotes " in your html. If you use single quotes, change the above part of the code to var target = $("a[name='" + name.substring(1) + "']");

Note 2: In some cases, especially when you use the sticky bar from the bootstrap, the named a will hide beneath the navigation bar. In those cases (or any similar case), you can reduce the number of the pixels from your scroll to achieve the optimal location. For example: $('html,body').animate({ scrollTop: $(target).offset().top - 15 }, 'slow'); will take you to the target with 15 pixels left on the top.

Ramtin
  • 3,058
  • 1
  • 22
  • 24
2

Ok simplest method is : -

Within the click function (Jquery) : -

$('html,body').animate({scrollTop: $("#resultsdiv").offset().top},'slow');

HTML

<div id="resultsdiv">Where I want to scroll to</div>
Mikeys4u
  • 1,494
  • 18
  • 26
  • 1
    this doesn't put the anchor in the url. Add `location.hash="#resultsdiv";` after the animation – Fanky Nov 25 '21 at 12:30
2

I stuck with my original code and also included a fade in 'back-to-top' link making use of this code and a bit from here too:

http://webdesignerwall.com/tutorials/animated-scroll-to-top

Works well :)

ade123
  • 2,773
  • 8
  • 29
  • 32
1

You may want to add offsetTop and scrollTop value in case You are animating not the whole page , but rather some nested content.

e.g :

var itemTop= $('.letter[name="'+id+'"]').offset().top;
var offsetTop = $someWrapper.offset().top;
var scrollTop = $someWrapper.scrollTop();
var y = scrollTop + letterTop - offsetTop

this.manage_list_wrap.animate({
  scrollTop: y
}, 1000);
TuxujPes
  • 76
  • 5
1

SS Slow Scroll

This solution does not require anchor tags but you do of course need to match the menu button (arbitrary attribute, 'ss' in example) with the destination element id in your html.

ss="about" takes you to id="about"

$('.menu-item').click(function() {
 var keyword = $(this).attr('ss');
 var scrollTo = $('#' + keyword);
 $('html, body').animate({
  scrollTop: scrollTo.offset().top
 }, 'slow');
});
.menu-wrapper {
  display: flex;
  margin-bottom: 500px;
}
.menu-item {
  display: flex;
  justify-content: center;
  flex: 1;
  font-size: 20px;
  line-height: 30px;
  color: hsla(0, 0%, 80%, 1);
  background-color: hsla(0, 0%, 20%, 1);
  cursor: pointer;
}
.menu-item:hover {
  background-color: hsla(0, 40%, 40%, 1);
}

.content-block-header {
  display: flex;
  justify-content: center;
  font-size: 20px;
  line-height: 30px;
  color: hsla(0, 0%, 90%, 1);
  background-color: hsla(0, 50%, 50%, 1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="menu-wrapper">
  <div class="menu-item" ss="about">About Us</div>
  <div class="menu-item" ss="services">Services</div>
  <div class="menu-item" ss="contact">Contact</div>
</div>

<div class="content-block-header" id="about">About Us</div>
<div class="content-block">
  Lorem ipsum dolor sit we gonna chung, crazy adipiscing phat. Nullizzle sapizzle velizzle, shut the shizzle up volutpizzle, suscipizzle quizzle, away vizzle, arcu. Pellentesque my shizz sure. Sed erizzle. I'm in the shizzle izzle funky fresh dapibus turpis tempus shizzlin dizzle. Maurizzle my shizz nibh izzle turpizzle. Gangsta izzle fo shizzle mah nizzle fo rizzle, mah home g-dizzle. I'm in the shizzle eleifend rhoncizzle fo shizzle my nizzle. In rizzle habitasse crazy dictumst. Yo dapibus. Curabitizzle tellizzle urna, pretizzle break it down, mattis izzle, eleifend rizzle, nunc. My shizz suscipit. Integer check it out funky fresh sizzle pizzle.

That's the shizzle et dizzle quis nisi sheezy mollis. Suspendisse bizzle. Morbi odio. Vivamizzle boofron. Crizzle orci. Cras mauris its fo rizzle, interdizzle a, we gonna chung amizzle, break it down izzle, pizzle. Pellentesque rizzle. Vestibulum its fo rizzle mi, volutpat uhuh ... yih!, ass funky fresh, adipiscing semper, fo shizzle. Crizzle izzle ipsum. We gonna chung mammasay mammasa mamma oo sa stuff brizzle yo. Cras ass justo nizzle purizzle sodales break it down. Check it out venenatizzle justo yo shut the shizzle up. Nunc crackalackin. Suspendisse bow wow wow placerizzle sure. Fizzle eu ante. Nunc that's the shizzle, leo eu gangster hendrerizzle, gangsta felis elementum pizzle, sizzle aliquizzle crunk bizzle luctus pede. Nam a nisl. Fo shizzle da bomb taciti gangster stuff i'm in the shizzle i'm in the shizzle per conubia you son of a bizzle, per inceptos its fo rizzle. Check it out break it down, neque izzle cool nonummy, tellivizzle orci viverra leo, bizzle semper risizzle arcu fo shizzle mah nizzle.
</div>
<div class="content-block-header" id="services">Services</div>
<div class="content-block">
Lorem ipsum dolor sit we gonna chung, crazy adipiscing phat. Nullizzle sapizzle velizzle, shut the shizzle up volutpizzle, suscipizzle quizzle, away vizzle, arcu. Pellentesque my shizz sure. Sed erizzle. I'm in the shizzle izzle funky fresh dapibus turpis tempus shizzlin dizzle. Maurizzle my shizz nibh izzle turpizzle. Gangsta izzle fo shizzle mah nizzle fo rizzle, mah home g-dizzle. I'm in the shizzle eleifend rhoncizzle fo shizzle my nizzle. In rizzle habitasse crazy dictumst. Yo dapibus. Curabitizzle tellizzle urna, pretizzle break it down, mattis izzle, eleifend rizzle, nunc. My shizz suscipit. Integer check it out funky fresh sizzle pizzle.

That's the shizzle et dizzle quis nisi sheezy mollis. Suspendisse bizzle. Morbi odio. Vivamizzle boofron. Crizzle orci. Cras mauris its fo rizzle, interdizzle a, we gonna chung amizzle, break it down izzle, pizzle. Pellentesque rizzle. Vestibulum its fo rizzle mi, volutpat uhuh ... yih!, ass funky fresh, adipiscing semper, fo shizzle. Crizzle izzle ipsum. We gonna chung mammasay mammasa mamma oo sa stuff brizzle yo. Cras ass justo nizzle purizzle sodales break it down. Check it out venenatizzle justo yo shut the shizzle up. Nunc crackalackin. Suspendisse bow wow wow placerizzle sure. Fizzle eu ante. Nunc that's the shizzle, leo eu gangster hendrerizzle, gangsta felis elementum pizzle, sizzle aliquizzle crunk bizzle luctus pede. Nam a nisl. Fo shizzle da bomb taciti gangster stuff i'm in the shizzle i'm in the shizzle per conubia you son of a bizzle, per inceptos its fo rizzle. Check it out break it down, neque izzle cool nonummy, tellivizzle orci viverra leo, bizzle semper risizzle arcu fo shizzle mah nizzle.
</div>
<div class="content-block-header" id="contact">Contact</div>
<div class="content-block">
  Lorem ipsum dolor sit we gonna chung, crazy adipiscing phat. Nullizzle sapizzle velizzle, shut the shizzle up volutpizzle, suscipizzle quizzle, away vizzle, arcu. Pellentesque my shizz sure. Sed erizzle. I'm in the shizzle izzle funky fresh dapibus turpis tempus shizzlin dizzle. Maurizzle my shizz nibh izzle turpizzle. Gangsta izzle fo shizzle mah nizzle fo rizzle, mah home g-dizzle. I'm in the shizzle eleifend rhoncizzle fo shizzle my nizzle. In rizzle habitasse crazy dictumst. Yo dapibus. Curabitizzle tellizzle urna, pretizzle break it down, mattis izzle, eleifend rizzle, nunc. My shizz suscipit. Integer check it out funky fresh sizzle pizzle.

That's the shizzle et dizzle quis nisi sheezy mollis. Suspendisse bizzle. Morbi odio. Vivamizzle boofron. Crizzle orci. Cras mauris its fo rizzle, interdizzle a, we gonna chung amizzle, break it down izzle, pizzle. Pellentesque rizzle. Vestibulum its fo rizzle mi, volutpat uhuh ... yih!, ass funky fresh, adipiscing semper, fo shizzle. Crizzle izzle ipsum. We gonna chung mammasay mammasa mamma oo sa stuff brizzle yo. Cras ass justo nizzle purizzle sodales break it down. Check it out venenatizzle justo yo shut the shizzle up. Nunc crackalackin. Suspendisse bow wow wow placerizzle sure. Fizzle eu ante. Nunc that's the shizzle, leo eu gangster hendrerizzle, gangsta felis elementum pizzle, sizzle aliquizzle crunk bizzle luctus pede. Nam a nisl. Fo shizzle da bomb taciti gangster stuff i'm in the shizzle i'm in the shizzle per conubia you son of a bizzle, per inceptos its fo rizzle. Check it out break it down, neque izzle cool nonummy, tellivizzle orci viverra leo, bizzle semper risizzle arcu fo shizzle mah nizzle.
</div>

Fiddle

https://jsfiddle.net/Hastig/stcstmph/4/

Hastig Zusammenstellen
  • 4,286
  • 3
  • 32
  • 45
1

I stumbled upon this example on https://css-tricks.com/snippets/jquery/smooth-scrolling/ explaining every line of code. I found this to be the best option.

https://css-tricks.com/snippets/jquery/smooth-scrolling/

You can go native:

window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth' 
});

window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

document.querySelector('.hello').scrollIntoView({ 
  behavior: 'smooth' 
});

or with jquery:

$('a[href*="#"]').not('[href="#"]').not('[href="#0"]').click(function(event) {

    if (
        location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') 
        && location.hostname == this.hostname
       ) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');

      if (target.length) {
        event.preventDefault();
        $('html, body').animate({
          scrollTop: target.offset().top
        }, 1000);
      }
    }
  });
Frankey
  • 3,679
  • 28
  • 25
-1
$(function() {
    $('a#top').click(function() {
        $('html,body').animate({'scrollTop' : 0},1000);
    });
});

Test it here:

http://jsbin.com/ucati4

Caelan
  • 940
  • 1
  • 7
  • 28
Sabi Singh
  • 43
  • 1
  • 3
    Please do not include signatures, especially ones with links... and *especially* ones with unrelated links. You can put that sort of thing in your profile. – Andrew Barber Jul 30 '13 at 12:44
  • The question asked was not how to scroll to the top of the page, it was how to scroll to an anchor with an id – user1380540 May 21 '15 at 18:22
  • Is there a way I can use that in WordPress?Am adding to my site but it doesn't really work. Here the link: http://scentology.burnnotice.co.za/ – Sidney Sousa Aug 25 '16 at 09:03
-1

following solution worked for me:

$("a[href^=#]").click(function(e)
        {
            e.preventDefault();
            var aid = $(this).attr('href');
            console.log(aid);
            aid = aid.replace("#", "");
            var aTag = $("a[name='"+ aid +"']");
            if(aTag == null || aTag.offset() == null)
                aTag = $("a[id='"+ aid +"']");

            $('html,body').animate({scrollTop: aTag.offset().top}, 1000);
        }
    );
Behrouz.M
  • 3,445
  • 6
  • 37
  • 64