【前言】
顺滑的意思是值动画帧数在60帧以上,也就是动画变化的时间间隔在16.6ms以下就可以到达顺滑的效果。由于setTimeout受影响的因素太多,所以平常顺滑版用requestAnimationFrame来实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body,
html {
height: 350%;
width: 350%;
}
div {
/* margin-left: 10px; */
}
#div1 {
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
top: 100px;
}
#div2 {
width: 100px;
height: 100px;
background-color: lightblue;
position: absolute;
top: 250px;
}
#div3 {
width: 100px;
height: 100px;
background-color: grey;
position: absolute;
top: 400px;
}
#btn1 {
position: fixed;
right: 50px;
bottom: 100px;
display: inline-block;
width: 100px;
height: 50px;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<button id="btn1">top</button>
<style>
</style>
<script>
/**
* 经测试,requestAnimationFrame会同步页面所有的动画函数的执行频率(渲染的时刻还是按照原先的函数执行时间来,只不过函数已经按照变化后的频率在后台执行了)
*
*
*
*
*
*/
function rowMove() { //左右元素的移动比较(非时间版)
let _right;
let start1 = true;
let startTime1 = 0;
let end1 = 0;
let start2 = true;
let startTime2 = 0;
let end2 = 0;
function moveDiv1(distance = 10) {
if (start1) {
startTime1 = Date.now();
start1 = false;
}
let ele = document.querySelector('#div1');
let masDistance = document.body.clientWidth;
let eleWidth = ele.offsetWidth; //元素总宽
_right = _right ? _right : masDistance - eleWidth;
if (_right > distance) {
_right = _right - distance;
ele.style.right = _right + 'px';
} else {
end1 = Date.now();
ele.style.right = 0;
console.log(end1 - startTime1)
throw 'settimeout'
}
}
function moveDiv2(distance = 10) {
if (start2) {
startTime2 = Date.now();
start2 = false;
}
let ele = document.querySelector('#div2');
let masDistance = document.body.clientWidth;
let eleWidth = ele.offsetWidth; //元素总宽
_right = _right ? _right : masDistance - eleWidth;
if (_right > distance) {
_right = _right - distance;
ele.style.right = _right + 'px';
} else {
end2 = Date.now();
ele.style.right = 0;
console.log(end2 - startTime2)
throw 'requestAnimationFrame'
}
}
function setTimeoutMove() { //非平滑移动
moveDiv1();
console.log('setTimeoutMove')
setTimeout(setTimeoutMove, 0);
}
function requerFrameAnimationMove() { //平滑移动
moveDiv2()
console.log('requerFrameAnimationMove')
requestAnimationFrame(requerFrameAnimationMove)
}
// setTimeoutMove();
requerFrameAnimationMove();
}
function scrollMove() { // 平滑移动时间版
let top;
let speed;
let startTime = Date.now();
top = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset;
function move(distance = 10, time = 1000) {
speed = (top / time);
distance = speed * (Date.now() - startTime);
top = top - distance;
document.documentElement.scrollTop = top;
if (top <= 0) {
throw 123
}
}
function stMove() {
try {
move();
setTimeout(stMove, 16.6)
} catch (e) {
return
}
}
function raf() {
try {
move();
requestAnimationFrame(raf)
} catch (e) {
return
}
}
// stMove()
raf()
}
// rowMove()
document.querySelector("#btn1").addEventListener('click', scrollMove, false)
</script>
</body>
</html>