I'm trying to make an animated "scroll to top" effect without using jQuery.

In jQuery, I usually use this code:

$('#go-to-top').click(function(){ $('html,body').animate({ scrollTop: 0 }, 400); return false; }); 

How do I animate scrollTop without using jQuery?

7

1 Answer

HTML:

<button onclick="scrollToTop(1000);"></button> 

1# JavaScript (linear):

function scrollToTop (duration) { // cancel if already on top if (document.scrollingElement.scrollTop === 0) return; const totalScrollDistance = document.scrollingElement.scrollTop; let scrollY = totalScrollDistance, oldTimestamp = null; function step (newTimestamp) { if (oldTimestamp !== null) { // if duration is 0 scrollY will be -Infinity scrollY -= totalScrollDistance * (newTimestamp - oldTimestamp) / duration; if (scrollY <= 0) return document.scrollingElement.scrollTop = 0; document.scrollingElement.scrollTop = scrollY; } oldTimestamp = newTimestamp; window.requestAnimationFrame(step); } window.requestAnimationFrame(step); } 

2# JavaScript (ease in and out):

function scrollToTop (duration) { // cancel if already on top if (document.scrollingElement.scrollTop === 0) return; const cosParameter = document.scrollingElement.scrollTop / 2; let scrollCount = 0, oldTimestamp = null; function step (newTimestamp) { if (oldTimestamp !== null) { // if duration is 0 scrollCount will be Infinity scrollCount += Math.PI * (newTimestamp - oldTimestamp) / duration; if (scrollCount >= Math.PI) return document.scrollingElement.scrollTop = 0; document.scrollingElement.scrollTop = cosParameter + cosParameter * Math.cos(scrollCount); } oldTimestamp = newTimestamp; window.requestAnimationFrame(step); } window.requestAnimationFrame(step); } /* Explanation: - pi is the length/end point of the cosinus intervall (see below) - newTimestamp indicates the current time when callbacks queued by requestAnimationFrame begin to fire. (for more information see ) - newTimestamp - oldTimestamp equals the delta time a * cos (bx + c) + d | c translates along the x axis = 0 = a * cos (bx) + d | d translates along the y axis = 1 -> only positive y values = a * cos (bx) + 1 | a stretches along the y axis = cosParameter = window.scrollY / 2 = cosParameter + cosParameter * (cos bx) | b stretches along the x axis = scrollCount = Math.PI / (scrollDuration / (newTimestamp - oldTimestamp)) = cosParameter + cosParameter * (cos scrollCount * x) */ 

Note:

  • Duration in milliseconds (1000ms = 1s)
  • Second script uses the cos function. Example curve:

enter image description here

3# Simple scrolling library on Github

11