前言
两者都是网页中定时器的操作,表示间隔多长时间执行回调函数,但是在间隔时长处理上是截然不同的,这就导致了他们使用的场景有所不同。
requestAnimationFrame
window.requestAnimationFrame()是一个全局的方法,它告诉浏览器你需要执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数来更新动画,该方法只需传入一个回调函数作为参数,不需要动画间隔时长。
requestAnimationFrame()方法自身只会调用一次,如果希望实现动画效果,则需要使用递归的方式循环调用
window.onload = function () {
const box = document.querySelector('.box')
let handlerId = null
let left = 0
const setAnimation = () => {
if (left > 500) {
// 取消动画执行
cancelAnimationFrame(handlerId)
return
}
handlerId = requestAnimationFrame(() => {
box.style.marginLeft = `${left++}px`
setAnimation()
})
}
setAnimation()
}
-
requestAnimationFrame动画执行的频率与显示器的刷新频率一致,显示器刷新频率大部分的是60Hz(每秒刷新60次), 算下来是每次间隔17ms左右,所以用来作为动画效果是非常合适的,不会出现卡顿,而setTimeout大概率会出现卡顿
-
requestAnimationFrame动画效果在当前浏览器标签被切换或者隐藏时,动画会停止工作,这样做的目的是节省性能以及电池的消耗
setTimeout
setTimout与requsetAnimationFrame用法类似,只是setTimeout定时器的间隔时间是手动设置的,由于js单线程原因,就会导致一个问题,回调函数的执行可能不会在间隔时间到来之际被执行,如果主线程繁忙,大概率会被延后执行,是不准确的, 这样就会导致动画的卡顿。
const timer = setTimeout(() => {
// to do...
console.log('hi')
}, 2000)
clearTimeout(timer)