308

I've been trying to get a scroll to div id jquery code to work correctly. Based on another stack overflow question i tried the following

DEMO http://jsfiddle.net/kevinPHPkevin/8tLdq/

$('#myButton').click(function() {
   $.scrollTo($('#myDiv'), 1000);
});

But it didn't work. It just snaps to the div. I also tried

$('#myButton').click(function(event) {
     event.preventDefault();
   $.scrollTo($('#myDiv'), 1000);
});

With no progress.

StevenPHP
  • 3,327
  • 3
  • 16
  • 18

15 Answers15

799

You need to animate the html, body

DEMO http://jsfiddle.net/kevinPHPkevin/8tLdq/1/

$("#button").click(function() {
    $('html, body').animate({
        scrollTop: $("#myDiv").offset().top
    }, 2000);
});
Kevin Lynch
  • 23,813
  • 2
  • 34
  • 37
  • 10
    @vector I have one issue, once it's clicked I have to fight with jquery to scroll up, any solution? – YesItsMe Apr 28 '15 at 19:39
  • @yesitsme ...up or down in my case – Gray Spectrum Jun 21 '16 at 03:07
  • 1
    @GraySpectrum up, only right after clicking, sounds like there's a delay. – YesItsMe Jun 21 '16 at 03:37
  • 1
    I have the same question, what if i have few buttons that need to scroll to different locations, tried modifying this code but it does not work. Could you please provide another example? – Dreadlord Jul 13 '16 at 13:18
  • Found some "fix" for it. Scrolling of the **proper element** is now fixed, but still it goes up and down by clicking on same "scroll-to" target: `var target = $(this).data("target"); $(".basics-content").animate({scrollTop: $(target).offset().top}, 1000); });` Explanation: `.basics-content` is the inner div of the modal which I actually want to scroll to, with `target` I provide the id number of the element ... – Roland Nov 14 '17 at 10:35
  • ... like: `data-target="#jump_xx_yy` and then the targeted element: `
    `.
    – Roland Nov 14 '17 at 13:05
  • i did the same but i got this error " Uncaught TypeError: Cannot read property 'top' of undefined" so what's the meaning of this can you help me...? – Sarfaraj Sipai Jun 05 '18 at 04:30
126

If you want to override standard href-id navigation on the page without changing the HTML markup for smooth scrolling, use this (example):

// handle links with @href started with '#' only
$(document).on('click', 'a[href^="#"]', function(e) {
    // target element id
    var id = $(this).attr('href');

    // target element
    var $id = $(id);
    if ($id.length === 0) {
        return;
    }

    // prevent standard hash navigation (avoid blinking in IE)
    e.preventDefault();

    // top position relative to the document
    var pos = $id.offset().top;

    // animated top scrolling
    $('body, html').animate({scrollTop: pos});
});
jarrodwhitley
  • 807
  • 8
  • 29
dizel3d
  • 3,510
  • 1
  • 20
  • 35
  • 3
    This works well, may I suggest a very small tweak `var pos = $(id).offset().top;` can be `var pos = $id.offset().top;` – Davey Jan 15 '17 at 16:01
  • Very nice. If you only want this to happen on certain links (say you have some to show or hide information), just add a class name to them and tack your class name (say scroller) to the end of the match declaration ( e.g. a[href^="#"].scroller ). – Privateer Feb 28 '17 at 14:00
  • How do you do that without jQuery? – Vadorequest May 06 '17 at 16:47
29

here is my 2 cents:

Javascript:

$('.scroll').click(function() {
    $('body').animate({
        scrollTop: eval($('#' + $(this).attr('target')).offset().top - 70)
    }, 1000);
});

Html:

<a class="scroll" target="contact">Contact</a>

and the target:

<h2 id="contact">Contact</h2>
Alexandre Mélard
  • 11,789
  • 3
  • 34
  • 45
15

Plain JS:

Can be done in plain JS if you use modern browsers.

document
    .getElementById("range-calculator")
    .scrollIntoView({ behavior: "smooth" });

Browser support is a bit issue, but modern browsers support it.

Nitin Jadhav
  • 5,159
  • 1
  • 43
  • 44
12

one example more:

HTML link:

<a href="#featured" class="scrollTo">Learn More</a>

JS:

  $(".scrollTo").on('click', function(e) {
     e.preventDefault();
     var target = $(this).attr('href');
     $('html, body').animate({
       scrollTop: ($(target).offset().top)
     }, 2000);
  });

HTML anchor:

  <div id="featured">My content here</div>
Eugen
  • 1,328
  • 12
  • 15
  • Earlier it was not scrolling to the top of the div, but then I made the below-mentioned changes and it worked. scrollTop: ($(target).offset().top - 120) – Akash Sethi Apr 27 '21 at 12:14
9

My solution for both Vanilla JS and jQuery

Vanilla JS:

document
    .querySelector("#myDiv")
    .scrollIntoView({ behavior: "smooth" });

jQuery:

You need to animate the html, body

$("#myButton").click(function() {
    $('html, body').animate({
        scrollTop: $("#myDiv").offset().top
    }, 2000);
});

CSS:

html {
  scroll-behavior: smooth;
}

Other properties of scroll-behavior

scroll-behavior: auto|smooth|initial|inherit;
Shuvo Habib
  • 1,876
  • 1
  • 18
  • 23
8

This code will be useful for any internal link on the web

    $("[href^='#']").click(function() {
        id=$(this).attr("href")
        $('html, body').animate({
            scrollTop: $(id).offset().top
        }, 2000);
    });
iDanielBH
  • 85
  • 2
  • 3
7

Here's what I use:

<!-- jquery smooth scroll to id's -->   
<script>
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    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) {
        $('html,body').animate({
          scrollTop: target.offset().top
        }, 500);
        return false;
      }
    }
  });
});
</script>

The beauty with this one is you can use an unlimited number of hash-links and corresponding ids without having to execute a new script for each.

If you’re using WordPress, insert the code in your theme’s footer.php file right before the closing body tag </body>.

If you have no access to the theme files, you can embed the code right inside the post/page editor (you must be editing the post in Text mode) or on a Text widget that will load up on all pages.

If you’re using any other CMS or just HTML, you can insert the code in a section that loads up on all pages right before the closing body tag </body>.

If you need more details on this, check out my quick post here: jQuery smooth scroll to id

Hope that helps, and let me know if you have questions about it.

5

are you sure you are loading the jQuery scrollTo Plugin file?

you might be getting a object: method not found "scrollTo" error in the console.

the scrollTO method is not a native jquery method. to use it you need to include the jquery scroll To plugin file.

ref: http://flesler.blogspot.in/2009/05/jqueryscrollto-142-released.html http://flesler.blogspot.in/2007/10/jqueryscrollto.html

soln: add this in the head section.

<script src="\\path\to\the\jquery.scrollTo.js file"></script>
MortalViews
  • 1,230
  • 12
  • 15
  • This should've been the accepted answer. The code in the question is correct, and works fine. It looks as though the scrollTo plugin isn't/wasn't working. . .He didn't ask about different ways to do something similar. – Chris Kavanagh Sep 09 '16 at 08:02
4

This script is a improvement of the script from Vector. I have made a little change to it. So this script works for every link with the class page-scroll in it.

At first without easing:

$("a.page-scroll").click(function() {
    var targetDiv = $(this).attr('href');
    $('html, body').animate({
        scrollTop: $(targetDiv).offset().top
    }, 1000);
});

For easing you will need Jquery UI:

<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

Add this to the script:

'easeOutExpo'

Final

$("a.page-scroll").click(function() {
    var targetDiv = $(this).attr('href');
    $('html, body').animate({
        scrollTop: $(targetDiv).offset().top
    }, 1000, 'easeOutExpo');
});

All the easings you can find here: Cheat Sheet.

3

This is the simplest.Source-https://www.w3schools.com/jsref/met_element_scrollintoview.asp

var elmnt = document.getElementById("content");
elmnt.scrollIntoView();
Suraj Rao
  • 28,850
  • 10
  • 94
  • 99
3

Here is my solution to smooth scroll to div / anchor using jQuery in case you have a fixed header so that it doesn't scroll underneath it. Also it works if you link it from other page.

Just replace ".site-header" to div that contains your header.

$(function() {

$('a[href*="#"]:not([href="#"])').click(function() {
var headerheight = $(".site-header").outerHeight();
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) {
    $('html, body').animate({
      scrollTop: (target.offset().top - headerheight)
    }, 1000);
    return false;
  }
}
});

//Executed on page load with URL containing an anchor tag.
if($(location.href.split("#")[1])) {
var headerheight = $(".site-header").outerHeight();
  var target = $('#'+location.href.split("#")[1]);
  if (target.length) {
    $('html,body').animate({
      scrollTop: target.offset().top - headerheight
    }, 1);
    return false;
  }
}
});
Mario
  • 31
  • 2
2

You can do it by using the following simple jQuery code.

Tutorial, Demo, and Source code can be found from here - Smooth scroll to div using jQuery

JavaScript:

$(function() {
    $('a[href*=#]:not([href=#])').click(function() {
        var target = $(this.hash);
        target = target.length ? target : $('[name=' + this.hash.substr(1) +']');
        if (target.length) {
            $('html,body').animate({
              scrollTop: target.offset().top
            }, 1000);
            return false;
        }
    });
});

HTML:

<a href="#section1">Go Section 1</a>
<div id="section1">
    <!-- Content goes here -->
</div>
JoyGuru
  • 1,675
  • 19
  • 9
2

Here I tried this, that work great for me.

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

    $('html, body').animate({
        scrollTop: $($(this).attr('href')).offset().top
    }, 500, 'linear');
});

HTML:

 <a href="#fast-food" class="active" data-toggle="tab" >FAST FOOD</a>

<div id="fast-food">
<p> Scroll Here... </p>
  </div>
Suraj Rao
  • 28,850
  • 10
  • 94
  • 99
waqas noor
  • 31
  • 1
0

This works to me.

<div id="demo">
        <h2>Demo</h2>
</div>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>
    $(document).ready(function () {
        // Handler for .ready() called.
        $('html, body').animate({
            scrollTop: $('#demo').offset().top
        }, 'slow');
    });
</script>

Thanks.

Y. Joy Ch. Singha
  • 2,637
  • 20
  • 23