330

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,547
  • 3
  • 17
  • 20

17 Answers17

839

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
  • 24,427
  • 3
  • 36
  • 37
  • 11
    @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
129

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
  • 826
  • 10
  • 29
dizel3d
  • 3,619
  • 1
  • 22
  • 35
  • 4
    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
30

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
  • 12,229
  • 3
  • 36
  • 46
19

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
  • 6,495
  • 1
  • 46
  • 48
  • 1
    Safari on iOS doesn't support this – HosseyNJF Jul 21 '20 at 17:49
  • 1
    Usual suspects. Safari on desktop also doesn't support it (according to MDN) – Nitin Jadhav Jul 22 '20 at 03:31
  • I have just tried safari desktop, and it is now working. – Derzu Nov 14 '21 at 14:57
  • 1
    I looked at several similar questions and this answer (using ...`.scrollIIntoView(`...`)`) is the only one that worked for me on a non-scrolling page with targets loaded within a scrolling div (Chrome 102.0.5005.61 (Official Build) (arm64)) – mikeypie Jun 10 '22 at 20:16
15

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
  • 2,035
  • 1
  • 20
  • 25
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,356
  • 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
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,250
  • 12
  • 16
  • 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
  • 29,388
  • 11
  • 94
  • 103
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,803
  • 20
  • 11
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
  • 29,388
  • 11
  • 94
  • 103
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
  • 3,056
  • 24
  • 26
0

Question is JQuery. Simplest should be below code. Make sure you include JQueryUI. Replace {version} with the latest version and off course here is the list for all methods you can use for animation. easeOutExpo with 2 seconds would give you very artistic scrolling.

Linear, swing, easeOutQuad, easeInQuad, easeInOutQuad, easeOutCubic, easeInCubic, easeInOutCubic, easeOutQuart, easeInQuart, easeInOutQuart, easeOutQuint, easeInQuint, easeInOutQunit, easeOutExpo, easeInExpo, easeInOutExpo, easeOutSine, easeInSine, easeInOutSine, easeOutCirc, easeInCirc, easeInOutCirc, easeOutElastic, easeInElastic, easeInOutElastic, easeOutBack, easeInBack, easeInOutBack, easeOutBounce, easeInBounce, easeInOutBounce

<script src="https://code.jquery.com/ui/{version}/jquery-ui.js"></script>

$('html, body').animate({ scrollTop: $("#id").offset().top }, 1000, "easeInExpo");
esenkaya
  • 99
  • 4
0

The latest javascript worked absolutely perfectly.

$('CLASS OR ID').on("click", function() {
        scrollTo($('#TARGETED CLASS OR ID / DIV'), 1000);
     });
haroon kiani
  • 199
  • 1
  • 5