I\'m looking for a simple, cross-browser \"scroll to top\" animation I can apply to a link. I don\'t want to require a JS library such as jQuery/Moo, etc.
//
I see that most/all of the above posts search for a button with javascript. This works, as long as you have only one button. I would recommend defining an "onclick" element inside the button. That "onclick" would then call the function causing it to scroll.
If you do it like that, you can use more than one button, as long as the button looks something like this:
<button onclick="scrollTo(document.body, 0, 1250)">To the top</button>
looks like there's a lot of solutions already. anyway, here's another one, uses easing equations..
// first add raf shim
// http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
// main function
function scrollToY(scrollTargetY, speed, easing) {
// scrollTargetY: the target scrollY property of the window
// speed: time in pixels per second
// easing: easing equation to use
var scrollY = window.scrollY || document.documentElement.scrollTop,
scrollTargetY = scrollTargetY || 0,
speed = speed || 2000,
easing = easing || 'easeOutSine',
currentTime = 0;
// min time .1, max time .8 seconds
var time = Math.max(.1, Math.min(Math.abs(scrollY - scrollTargetY) / speed, .8));
// easing equations from https://github.com/danro/easing-js/blob/master/easing.js
var easingEquations = {
easeOutSine: function (pos) {
return Math.sin(pos * (Math.PI / 2));
},
easeInOutSine: function (pos) {
return (-0.5 * (Math.cos(Math.PI * pos) - 1));
},
easeInOutQuint: function (pos) {
if ((pos /= 0.5) < 1) {
return 0.5 * Math.pow(pos, 5);
}
return 0.5 * (Math.pow((pos - 2), 5) + 2);
}
};
// add animation loop
function tick() {
currentTime += 1 / 60;
var p = currentTime / time;
var t = easingEquations[easing](p);
if (p < 1) {
requestAnimFrame(tick);
window.scrollTo(0, scrollY + ((scrollTargetY - scrollY) * t));
} else {
console.log('scroll done');
window.scrollTo(0, scrollTargetY);
}
}
// call it once to get started
tick();
}
// scroll it!
scrollToY(0, 1500, 'easeInOutQuint');
Without JQuery code, Hope this will help you.
function TopscrollTo() {
if(window.scrollY!=0)
{
setTimeout(function() {
window.scrollTo(0,window.scrollY-30);
TopscrollTo();
}, 100);
}
}
call this TopscrollTo() function on button click event or on any other element/event which you want.
No one mentioned the CSS property scroll-behavior
CSS
html {
scroll-behavior: smooth;
}
JS
window.scrollTo(0,0)
Building on some of the answers here, but using some simple math for a smooth transition using a sine curve:
scrollTo(element, from, to, duration, currentTime) {
if (from <= 0) { from = 0;}
if (to <= 0) { to = 0;}
if (currentTime>=duration) return;
let delta = to-from;
let progress = currentTime / duration * Math.PI / 2;
let position = delta * (Math.sin(progress));
setTimeout(() => {
element.scrollTop = from + position;
this.scrollTo(element, from, to, duration, currentTime + 10);
}, 10);
}
Usage:
// Smoothly scroll from current position to new position in 1/2 second.
scrollTo(element, element.scrollTop, element.scrollTop + 400, 500, 0);
PS. take note of ES6 style
Adapted from this answer:
function scroll(y, duration) {
var initialY = document.documentElement.scrollTop || document.body.scrollTop;
var baseY = (initialY + y) * 0.5;
var difference = initialY - baseY;
var startTime = performance.now();
function step() {
var normalizedTime = (performance.now() - startTime) / duration;
if (normalizedTime > 1) normalizedTime = 1;
window.scrollTo(0, baseY + difference * Math.cos(normalizedTime * Math.PI));
if (normalizedTime < 1) window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
}
This should allow you to smoothly scroll (cosine function) from anywhere to the specified "y".