0

使用requestAnimationFrame实现类似setInterval的计时器

Nnnina 5
2018-03-22 提问
2 个回答
2

供参考,没有实现字符串功能,反正也不推荐使用。

function setInterval2 (cb, delay, ...args) {
  // 记录所有正在运行的 interval 用于撤销
  let pool = window[Symbol.for('IntervalPool')]
  if (!pool) {
    pool = {}
    window[Symbol.for('IntervalPool')] = pool
  }

  // interval 最低 10ms,虽然每 frame 至少得 16ms
  delay = delay >= 10 ? delay : 10
  // interval id
  let ticket = Date.now()
  // 每次 interval 开始时间
  let startTime = ticket
  pool[ticket] = true
  loop()
  return ticket

  function loop () {
    if (!pool[ticket]) { return }
    const now = Date.now()
    if (now - startTime >= delay) {
      startTime = now
      cb(...args)
    }
    requestAnimationFrame(loop)
  }
}

function clearInterval2 (ticket) {
  let pool = window[Symbol.for('IntervalPool')]
  if (pool && pool[ticket]) {
    delete pool[ticket]
  }
}
0
function a(callback){
       requestAnimationFrame(function(){
           //你的代码
           callback && callback()
           a()
       })
}

需要注意requestAnimationFrame的浏览器兼容性问题

window.requestAnimationFrame = window.requestAnimationFrame || 
window.webkitRequestAnimationFrame || 
window.mozRequestAnimationFrame || 
window.msRequestAnimationFrame || 
window.oRequestAnimationFrame || 
function (callback) {
    //为了使setTimteout的尽可能的接近每秒60帧的效果
    window.setTimeout(callback, 1000 / 60);
};
    
window.cancelAnimationFrame = window.cancelAnimationFrame || 
Window.webkitCancelAnimationFrame || 
window.mozCancelAnimationFrame || 
window.msCancelAnimationFrame || 
window.oCancelAnimationFrame || 
function (id) {
    //为了使setTimteout的尽可能的接近每秒60帧的效果
    window.clearTimeout(id);
}

撰写答案

你可能感兴趣的

推广链接