Smooth Scroll Without jQuery

Photo by: Anni Roenkae

You must have seen the special effect where you click on a link and your browser scrolls to the appropriate section smoothly.

With jQuery

Basic usage

Here’s how to make a smooth scroll with jQuery. If you put this snippet of code in a script tag, it will scroll the page down to the section with id of ‘target-element’.

$("html, body").animate(
  {
    scrollTop: $("#target-element").offset().top,
  },
  1000
);

More practical usage

With the following code, it will make your page scroll to the selected anchor smoothly for every link.

(function () {
  $(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 });
  });
})();

Without jQuery

I do think jQuery is pretty handy, but it’s better that we know how things really works without jQuery. So, how can I get the same special effect with JavaScript only?

The essential idea of scrolling, is changing an element’s scrollTop value, we need to know for each point in time, what the scrollTop value should be. And to make the scroll smoothly, we need to “continuously” change that value until the scroll is completed.

function smoothScroll(target, time) {
  // time when scroll starts
  var start = new Date().getTime(),
    // set an interval to update scrollTop attribute every 25 ms
    timer = setInterval(function () {
      // calculate the step, i.e the degree of completion of the smooth scroll
      var step = Math.min(1, (new Date().getTime() - start) / time);

      // calculate the scroll distance and update the scrollTop
      document.body["scrollTop"] = step * target.offsetTop;

      // end interval if the scroll is completed
      if (step == 1) {
        clearInterval(timer);
      }
    }, 25);
}

In HTML, add a onclick (or other) event to use the smoothScroll function we just created.

<!-- my trigger -->
<a
  id="trigger"
  href="#"
  onclick="smoothScroll(document.getElementById('aa'), 2000)"
  >link</a
>
<!-- other content -->
<div style="height: 500px;"></div>

<!-- my target section -->
<div id="aa">aaaaaaaaaaaaaaaaaaaaaa</div>

This is how to scroll smoothly without jQuery.


  TOC