Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scroll top/bottom of the screen on button click using JavaScript not jQuery also It should work in chrome, IE & mozilla

Tags:

javascript

css

I wanted to implement a simple top and bottom scroll on button click. the scroll should be smooth in all browsers.

Requirements -

I have two buttons on the page, on top of the page there is a button called Down on clicking on that It should go down to the footer div.

There is one more button on the bottom of the page called UP on clicking on that It should go up of the screen.

I have tried one solution but in IE, the scroll is not smooth. How can we make the scroll behavior smooth in all browsers.

Currently I have used the scroll-behavior property in CSS but is it a good practice? Is there any way to do it in JavaScript instead of CSS?

html{
  scroll-behavior: smooth;
}

NOTE: It should also work in IE.

I would really appreciate your help.

Link of codepen for code- https://codepen.io/Akkanksha1/full/KKgWmgL

like image 530
Akanksha Mohanty Avatar asked Dec 15 '20 10:12

Akanksha Mohanty


1 Answers

This solution is written in ECMAScript 5 and makes use of requestAnimationFrame() in order to synchronize the step calculations with the screen framerate. It works in IE and in modern browsers as well. It implements the easeInOutCubic function, and could be extended to support other easing functions.

function getProgress(_ref) {
  var duration = _ref.duration,
      runTime = _ref.runTime;
  var percentTimeElapsed = runTime / duration;

  function easeOutCubic(x) {
      return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2 ;
  }

  return easeOutCubic(percentTimeElapsed);
};

function getTotalScroll(_ref) {
  var scrollableDomEle = _ref.scrollableDomEle,
      elementLengthProp = _ref.elementLengthProp,
      initialScrollPosition = _ref.initialScrollPosition,
      scrollLengthProp = _ref.scrollLengthProp,
      direction = _ref.direction;
  var totalScroll;

  var documentElement = document.documentElement;
  totalScroll = documentElement.offsetHeight;
  
  return !!~['left', 'top'].indexOf(direction) ? initialScrollPosition : totalScroll - initialScrollPosition;
};

function smoothScroll(_ref2) {
  var scrollableDomEle = window,
      direction = _ref2.direction,
      duration = _ref2.duration,
      scrollAmount = window.outerHeight - window.innerHeight;
  var startTime = null,
      scrollDirectionProp = null,
      scrollLengthProp = null,
      elementLengthProp = null,
      scrollDirectionProp = 'pageYOffset';
      elementLengthProp = 'innerHeight';
      scrollLengthProp = 'scrollHeight';

  var initialScrollPosition = scrollableDomEle[scrollDirectionProp];
  var totalScroll = getTotalScroll({
    scrollableDomEle: scrollableDomEle,
    elementLengthProp: elementLengthProp,
    initialScrollPosition: initialScrollPosition,
    scrollLengthProp: scrollLengthProp,
    direction: direction
  });

  if (!isNaN(scrollAmount) && scrollAmount < totalScroll) {
    totalScroll = scrollAmount;
  }

  var scrollOnNextTick = function scrollOnNextTick(timestamp) {
    var runTime = timestamp - startTime;
    var progress = getProgress({
      runTime: runTime,
      duration: duration
    });

    if (!isNaN(progress)) {
      var scrollAmt = progress * totalScroll;
      var scrollToForThisTick = direction === 'bottom' ? scrollAmt + initialScrollPosition : initialScrollPosition - scrollAmt;

      if (runTime < duration) {
        var xScrollTo = 0;
        var yScrollTo = scrollToForThisTick;
        window.scrollTo(xScrollTo, yScrollTo);

        requestAnimationFrame(scrollOnNextTick);
      } else {
        var _scrollAmt = totalScroll;
        var scrollToForFinalTick = direction === 'bottom' ? _scrollAmt + initialScrollPosition : initialScrollPosition - _scrollAmt;
        var _xScrollTo = 0;
        var _yScrollTo = scrollToForFinalTick;
        window.scrollTo(_xScrollTo, _yScrollTo);
      }
    }
  };

  requestAnimationFrame(function (timestamp) {
    startTime = timestamp;
    scrollOnNextTick(timestamp);
  });
};


function scrollToTop() {
  smoothScroll({ duration: 2000, direction: 'top' });
}

function scrollToBottom() {
  smoothScroll({ duration: 2000, direction: 'bottom' });
}

document.getElementById('scroll-to-bottom').addEventListener('click', scrollToBottom);
document.getElementById('scroll-to-top').addEventListener('click', scrollToTop);
.container {
  position: relative;
  height: 1000px;
  background-color: red
}

#scroll-to-bottom {
  position: absolute;
  top: 0px;
}

#scroll-to-top {
  position: absolute;
  bottom: 0px;
}
<div class="container">
  <button id="scroll-to-bottom">Scroll to bottom</button>
  <button id="scroll-to-top">Scroll to top</button>
</div>
like image 149
Guerric P Avatar answered Sep 28 '22 11:09

Guerric P