我正在寻找一个简单的,跨浏览器“滚动到顶部”的动画,我可以应用到一个链接。我不想需要一个JS库,如jQuery/Moo等。
// jQuery Equivilant to convert to pure JS...
$('html, body').animate({scrollTop:0}, 400);
对于那些在跳进图书馆之前应该100%学习JS的人来说,我是一个完美的例子。:(
我正在寻找一个简单的,跨浏览器“滚动到顶部”的动画,我可以应用到一个链接。我不想需要一个JS库,如jQuery/Moo等。
// jQuery Equivilant to convert to pure JS...
$('html, body').animate({scrollTop:0}, 400);
对于那些在跳进图书馆之前应该100%学习JS的人来说,我是一个完美的例子。:(
当前回答
我修改了TimWolla的答案,使用二次输入-输出缓和(更流畅一点:)。下面是一个正在运行的示例:在jsFiddle上。这里提供了缓动函数:Robert Penner的缓动函数
document.getElementsByTagName('button')[0].onclick = function () {
scrollTo(document.body, 0, 1250);
}
function scrollTo(element, to, duration) {
var start = element.scrollTop,
change = to - start,
increment = 20;
var animateScroll = function(elapsedTime) {
elapsedTime += increment;
var position = easeInOut(elapsedTime, start, change, duration);
element.scrollTop = position;
if (elapsedTime < duration) {
setTimeout(function() {
animateScroll(elapsedTime);
}, increment);
}
};
animateScroll(0);
}
function easeInOut(currentTime, start, change, duration) {
currentTime /= duration / 2;
if (currentTime < 1) {
return change / 2 * currentTime * currentTime + start;
}
currentTime -= 1;
return -change / 2 * (currentTime * (currentTime - 2) - 1) + start;
}
其他回答
我已经选择了@timwolla answer的@akai版本,并添加了stopAnimation函数作为返回,所以在开始新的动画之前,旧的动画可以停止。
if ( this.stopAnimation )
this.stopAnimation()
this.stopAnimation = scrollTo( el, scrollDestination, 300 )
// definitions
function scrollTo(element, to, duration) {
var start = element.scrollTop,
change = to - start,
increment = 20,
timeOut;
var animateScroll = function(elapsedTime) {
elapsedTime += increment;
var position = easeInOut(elapsedTime, start, change, duration);
element.scrollTop = position;
if (elapsedTime < duration) {
timeOut = setTimeout(function() {
animateScroll(elapsedTime);
}, increment);
}
};
animateScroll(0);
return stopAnimation
function stopAnimation() {
clearTimeout( timeOut )
}
}
function easeInOut(currentTime, start, change, duration) {
currentTime /= duration / 2;
if (currentTime < 1) {
return change / 2 * currentTime * currentTime + start;
}
currentTime -= 1;
return -change / 2 * (currentTime * (currentTime - 2) - 1) + start;
}
window.scroll({top: 0, left: 0, behavior: 'smooth' });
从一篇关于平滑滚动的文章中得到的。
如果需要,可以使用一些填充物。
JS解决方案w/o jQuery。
element.onclick = () => window.scrollTo({ top: 0, behavior: 'smooth' })
看来已经有很多解决方案了。不管怎样,这是另一个,使用简化方程。
// 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');
实际上有一个纯javascript的方式来完成这个不使用setTimeout或requestAnimationFrame或jQuery。
简而言之,在scrollView中找到要滚动到的元素,并使用scrollIntoView
el.scrollIntoView({行为:“平滑”});
这是一个普朗克。