說在前頭
requestAnimationFrame靠的是刷新頻率“幀”,具體的概念我就不細說了,總之就是setInterval的替代品,對於一些平滑無時間間隔的動畫來說性能更優一些。
一、方法定義
const M = ((W) => {
let arr = [] // 閉包作用域
// 不用變量定義,該對象本來就在全局
W.requestAnimationFrame = W.requestAnimationFrame || W.mozRequestAnimationFrame || W.webkitRequestAnimationFrame || W.msRequestAnimationFrame
return {
setInterval (fn) { // 模擬函數名 --- 循環
const len = arr.length
arr[len] = { // 建立動畫對象
'for' () {},
'animate': 0
}
arr[len].for = () => { // 存在閉包內
fn()
if (!arr[len]) { // 如果該對象被刪除了,則退出遞歸
return
}
arr[len].animate = W.requestAnimationFrame(arr[len].for) // 遞歸調用
}
arr[len].animate = W.requestAnimationFrame(arr[len].for)
return {
index: len, // 返回arr數組內動畫對象的下標
obj: arr[len], // 返回當前動畫對象
arr: arr // 返回所有生成過的對象,便於外部控制與手動釋放
}
},
clearInterval (obj) { // 清空
if (!obj || !obj.arr) {
return
}
W.cancelAnimationFrame(obj.obj.animate) // 默認清除當前傳進來的對象
obj.obj.animate = obj.obj.for = null // 斷開依賴關係,釋放內存
delete arr[obj.index] // 刪除對象
}
}
})(window)
當然也可以封裝成構造函數模式
二、方法調用
let raf = M.setInterval(() => {
// do something......
if (/* 判斷條件 */) {
M.clearInterval(raf)
}
}) // raf動畫不支持定時執行,如果要加的話,內部封裝仍然是要用setTimeout的
並沒有封裝setTimeout的,如只需執行一遍,那就同步執行完再手寫清除,或修改下封裝代碼會更簡單。
關於
make:o︻そ╆OVE▅▅▅▆▇◤(清一色天空)
blog:http://blog.csdn.net/mcky_love
掘金:https://juejin.im/user/59fbe6c66fb9a045186a159a/posts
結束語
性能是個大坑,大家一起向前匍匐摸索。