使用requestAnimationFrame模拟实现setTimeout和setInterval

rafTimeout 函数与 setTimeout 和 setInterval 用法基本一致!

接受参数:

  • fn:延迟 delay ms 后要执行的函数

  • delay(可选):延迟的毫秒数,默认 0ms

  • interval(可选):默认情况下 rafTimeout 等效于 setTimeout 功能,如果要使用 setInterval 功能,则需传入第三个参数(interval: true)

返回值(用于取消 rafTimeout):

  • raf: { id: number }

取消 rafTimeout 定时器:

  • cancelRaf(raf)

  • cancelAnimationFrame(raf.id)

// @ts-ignore 兼容性 requestAnimationFrame
export const requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
// @ts-ignore 兼容性 cancelAnimationFrame
export const cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
// 使用 requestAnimationFrame 模拟 setTimeout 和 setInterval
export function rafTimeout (fn: Function, delay = 0, interval = false): object {
  // @ts-ignore
  const requestAnimationFrame = typeof window !== 'undefined' ? (window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame) : () => {}
  var start: any = null
  function timeElapse (timestamp: number) {
    /*
      timestamp参数:与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行回调函数的时刻
    */
    if (!start) {
      start = timestamp
    }
    const elapsed = timestamp - start
    if (elapsed >= delay) {
      fn() // 执行目标函数func
      if (interval) { // 使用间歇调用
        start = null
        raf.id = requestAnimationFrame(timeElapse)
      }
    } else {
      raf.id = requestAnimationFrame(timeElapse)
    }
  }
  const raf = { // 引用类型保存,方便获取 requestAnimationFrame()方法返回的 ID.
    id: requestAnimationFrame(timeElapse)
  }
  return raf
}
// 用于取消 rafTimeout 函数
export function cancelRaf (raf: { id: number }): void {
  // @ts-ignore
  const cancelAnimationFrame = typeof window !== 'undefined' ? (window.cancelAnimationFrame || window.mozCancelAnimationFrame) : () => {}
  if (raf && raf.id) {
    cancelAnimationFrame(raf.id)
  }
}

你可能感兴趣的:(ts,js,typescript,javascript)