2

I am having some issues trying to smoothly scroll to an element using vanilla JavaScript.

I have a one-page website with 3 links. When I click one of the links, I want smooth scrolling to the section that it represents. I have a jQuery version, and that is working great, but I would like to learn how to achieve the same result using vanilla JavaScript.

The question has been asked before but the answers are a bit complicated. I believe there should be a cleaner and easier answer to that.

Thanks.

jQuery code :

$('a').click(function(){
    $('html, body').animate({
        scrollTop: $( $(this).attr('href') ).offset().top
    }, 1000);
    return false;
});
Robin Daugherty
  • 7,115
  • 4
  • 45
  • 59
NoName84
  • 407
  • 3
  • 12
  • 25
  • What exactly is wrong?Provide a fiddle. – Satej S Apr 14 '16 at 10:18
  • I would like to achieve the same result as the jQuery code but using vanilla Javascript. I cant figure how to achieve it. I would appreciate it if someone with a good knowledge of Javascript can write the code. – NoName84 Apr 14 '16 at 10:22

1 Answers1

4

You'll need some easing functions for smooth vanilla js scrolling.

Robert Penner is the easing man

I have a demo on jsbin I did some time ago for a HTML5 course. You might be interested in the sources.

demo function for scrolling used in the example above:

function scrollToItemId(containerId, srollToId) {

        var scrollContainer = document.getElementById(containerId);
        var item = document.getElementById(scrollToId);

        //with animation
        var from = scrollContainer.scrollTop;
        var by = item.offsetTop - scrollContainer.scrollTop;
        if (from < item.offsetTop) {
            if (item.offsetTop > scrollContainer.scrollHeight - scrollContainer.clientHeight) {
                by = (scrollContainer.scrollHeight - scrollContainer.clientHeight) - scrollContainer.scrollTop;
            }
        }

        var currentIteration = 0;

        /**
         * get total iterations
         * 60 -> requestAnimationFrame 60/second
         * second parameter -> time in seconds for the animation
         **/
        var animIterations = Math.round(60 * 0.5); 

        (function scroll() {
            var value = easeOutCubic(currentIteration, from, by, animIterations);
            scrollContainer.scrollTop = value;
            currentIteration++;
            if (currentIteration < animIterations) {
                requestAnimationFrame(scroll);
            }    
        })();

        //without animation
        //scrollContainer.scrollTop = item.offsetTop;

    }

    //example easing functions
    function linearEase(currentIteration, startValue, changeInValue, totalIterations) {
        return changeInValue * currentIteration / totalIterations + startValue;
    }
    function easeOutCubic(currentIteration, startValue, changeInValue, totalIterations) {
        return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue;
    }
michaPau
  • 1,598
  • 18
  • 24