Have you ever tried to replicate the smooth scroll animation of jQuery scrollTop but without jQuery? With plain / vanilla Javascript?

I did, and let me tell you it is not something you find on the “You don’t need jQuery” webpages. And it even gets more complicated when you want to apply a specific jQuery easing effect, fire a callback on finish, being able to stop the animation at any moment etc.

You could go and make use of a smooth scrolling library like this but it is 5Kb with polyfills and minified and it does a lot more than scrolling. It deals with link anchors and the text within them and it has quite a lot of logic dedicated at that. Something perhaps unnecessary if you just want to scroll smootly.

Lightweight Javascript effect

If you want something much smaller to use within your code, here’s hat I’ve used for my fullPage.js library.

It is only 0.4Kb minified and pretty straight forward.

I’ve made it available at Github just before writing this article so you can have access to it all as well as the minified files.

Demo View on GitHub

/*!
 * skrollTop 0.0.1
 * https://github.com/alvarotrigo/skrollTop.js
 * @license MIT
 *
 * Copyright (C) 2018 alvarotrigo.com - A project by Alvaro Trigo
 */
(function (root, factory) {
  if ( typeof define === 'function' && define.amd ) {
    define([], (function () {
      return factory(root, root.document);
    }));
  } else if ( typeof exports === 'object' ) {
    module.exports = factory(root, root.document);
  } else {
    root.skrollTop = factory(root, root.document);
  }
})(typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this, (function (window, document) {
    'use strict';

    var g_activeAnimation;
    var self = {};

    //easeInOutCubic animation included in the library
    Math.easeInOutCubic = function (t, b, c, d) {
        if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;
    };

    self.stop = function(){
        g_activeAnimation = false;
    };

    /**
    * Simulates the animated scrollTop of jQuery. Used when css3:false or scrollBar:true or autoScrolling:false
    * http://stackoverflow.com/a/16136789/1081396
    */
   self.scrollTo = function(params) {
       var element = typeof params.element !== 'undefined' ? params.element : window;
       var to = params.to;
       var duration = typeof params.duration !== 'undefined' ? params.duration : 700;
       var callback = typeof params.callback !== 'undefined' ? params.callback : null;
       var easing = typeof params.easing !== 'undefined' ? params.easing : Math.easeInOutCubic;

       var start = (window.pageYOffset || document.documentElement.scrollTop)  - (document.documentElement.clientTop || 0);
       var change = to - start;
       var currentTime = 0;
       var increment = 16; //same amount of milliseconds as requestAnimationFrame
       g_activeAnimation = true;

       var animateScroll = function() {
            //in case we want to stop it from other function whenever we want
           if (g_activeAnimation) {
               currentTime += increment;
               element.scrollTo(0, easing(currentTime, start, change, duration));

               if (currentTime < duration) {
                   setTimeout(animateScroll, increment);
               } else if (callback){
                   callback();
               }
           }else if (currentTime < duration && callback){
               callback();
           }
       };

       animateScroll();
   };

   return self;
}));

In order to use it just call skrollTop.scrollTo like this:

document.getElementById('scrollMe').addEventListener('click', function(){
    skrollTop.scrollTo({
        to: 800,
        duration: 4000,
        callback: function() {
           console.log("va");
        }
    });
});

How to add jQuery easing effects

jQuery UI scrollTop easing effects

jQuery provides a small set of animation effects they call Easings Functions. If you want to have access to more effects, then you would have to go for jQuery UI

The library includes the easeInOutCubic effect, but you can add any others provided by jQuery by using the vendor file easings.min.js (only 12Kb) that I also provide in fullPage.js. Then just passs the name of the effect as an option to the library to specify which easing you want to use:

<!-- Optional ! -->
<script type="text/javascript" src="../easings.js"></script>
<!-- end of optional -->

<script type="text/javascript" src="../skrollTop.js"></script>
    skrollTop.scrollTo({
        to: 800,
        easing: window.easings.easeOutBounce, // <-- here!
        duration: 600,
        callback: function() {
           console.log("finished!");
        }
    });