requestAnimationFrame 没有触发提供给它的函数

requestAnimationFrame is not triggering the function supplied to it

我使用 setInterval 实现了无限循环动画。我现在想将实现更改为 requestAnimationFrame(),这样我就能获得我想要的性能。由于某些原因,requestAnimationFrame() 不会调用提供给它的函数。

我的代码是这样的;

var index = 0;
var $btn = $('.btn');
function btnBlinkRun() {
  if (index < 2) {
    index = index + 1;
  } else {
    index = 0;
  }
  $('#ani--scaleinout').removeAttr('id');
  $($btn[index]).attr('id', 'ani--scaleinout');
  window.requestAnimationFrame(btnBlinkRun);
}

btnBlinkRun();
.btn{
  width: 30px;
  height: 30px;
  
  background: blue;
  border-radius: 100%;
  margin-bottom: 10px;
}

#ani--scaleinout {
  animation: zoominout 1s ease-in;
}

@keyframes zoominout {
    50% {
        transform: scale(1.4);
    }
    100% {
        transform: scale(1);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  
  <div class="btn" id="ani--scaleinout"></div>
    <div class="btn"></div>

    <div class="btn"></div>

  
</div>

看起来你每秒发射 requestAnimationFrame 多次。您的 css 动画持续时间为 1s。但是您每 x 毫秒删除一次属性。

它正在触发,它发生得如此之快以至于你看不到它。为了演示更改对 window.requestAnimationFrame 的调用以使用 setTimeout,您会注意到动画:

setTimeout(function() {
    window.requestAnimationFrame(btnBlinkRun);
}, 1000);

不是说这是首选解决方案,而是解释为什么会这样。

它执行得很好。但我想它不会做你想做的事。 动画帧在每个渲染帧(例如 60fps)上触发,而不是在 CSS 个动画关键帧上触发。

animationend 活动是你的朋友。

var index = 0;
var buttons = document.querySelectorAll('.btn');
function btnBlinkRun() {
  if (index < 2) {
    index = index + 1;
  } else {
    index = 0;
  }
  const element = document.querySelector('#ani--scaleinout');
  element.id = null;
  buttons[index].id = 'ani--scaleinout';
  buttons[index].addEventListener("animationend", btnBlinkRun, { once: true });
}

btnBlinkRun();
.btn{
  width: 30px;
  height: 30px;
  
  background: blue;
  border-radius: 100%;
  margin-bottom: 10px;
}

#ani--scaleinout {
  animation: zoominout 1s ease-in;
}

@keyframes zoominout {
    50% {
        transform: scale(1.4);
    }
    100% {
        transform: scale(1);
    }
}
<div>
  <div class="btn" id="ani--scaleinout"></div>
  <div class="btn"></div>
  <div class="btn"></div>
</div>