【库】requestAnimationFrame:raf封装为setInterval格式,书写更加得心应手

说在前头

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


结束语

性能是个大坑,大家一起向前匍匐摸索。

你可能感兴趣的:(JS编写规范)