我的ul里面有一些li
。
我想随机选择li
并添加.active
类1秒,然后移除.active
类并随机选择下一个li
。
我试图在不使用setInterval或Timeout的情况下这样做,所以我尝试使用requestAnimationFrame虽然我认为我的javascript逻辑在随机化方面不太正确。
目前我已经开始工作,但每次再次调用该函数时它会选择相同的li
。
<ul>
<li class="light active"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
</ul>
Javascript
(function() {
var lights = document.getElementsByClassName("light");
var random = Math.floor(Math.random() * (lights.length - 1)) + 0;
var randomLight = lights[random];
function repeatOften() {
randomLight.classList += randomLight.classList ? ' active' : ' light';
requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);
})();
这是一支笔:https://codepen.io/H0BB5/pen/PJjapX?editors=0010
提前致谢!
答案 0 :(得分:0)
在将来或多或少知道的时间内运行函数的正确选择是setTimeout
。 requestAnimationFrame
适用于在不中断渲染循环的情况下尽可能经常运行的事情,例如每秒60次(又名&#34; 60 fps&#34;)。
在您的情况下,您的更新速度相对较慢,每秒一次,因此setTimeout
不会受到伤害。
您可能希望跟踪两个元素:您正在更改的元素和之前更改的元素,因此您可以重置它。
另外,classList.toggle
会派上用场,因为它会添加或删除一个类,具体取决于它是否已经存在。
(function() {
var lights = document.getElementsByClassName("light");
var previousLight = null;
function repeatOften() {
if (previousLight) previousLight.classList.toggle('active')
var random = Math.floor(Math.random() * (lights.length - 1)) + 0;
var randomLight = lights[random];
randomLight.classList.toggle(randomLight);
previousLight = randomLight;
setTimeout(repeatOften, 1000);
}
setTimeout(repeatOften, 1000);
})();
Here是更新的(稍有更改)笔。
答案 1 :(得分:0)
每次运行该功能时,您都需要更新闪烁的灯光。要每秒进行不同的光线变化,请检查动画帧时间是否为秒。
(function repeatOften(ts) {
if (ts % 1000 < 10) {
document.getElementsByClassName("active")[0].classList.remove('active');
var lights = document.getElementsByClassName("light");
lights[Math.floor(Math.random() * lights.length)].classList.add('active');
}
requestAnimationFrame(repeatOften);
})();
&#13;
li {
background: 1px black
}
li.active {
animation: blink 1s ease-in-out infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
&#13;
<ul>
<li class="light active"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
</ul>
&#13;
答案 2 :(得分:0)
我试图在不使用setInterval或Timeout
的情况下执行此操作
当前CSS动画完成时,您可以使用animationend
事件来调用相同的函数
function fn() {
var lights = document.querySelectorAll(".light");
var random = Math.floor(Math.random() * lights.length);
var randomLight = lights[random];
repeatOften(randomLight)
};
function repeatOften(randomLight) {
randomLight.className = "light active";
randomLight.addEventListener("animationend", blink)
}
function blink() {
this.className = "light";
this.removeEventListener("animationend", blink);
fn();
}
// handle first `li`
document.querySelector(".light.active")
.addEventListener("animationend", blink)
&#13;
.light.active {
animation: blink 1s ease-in-out;
}
@keyframes blink {
50% {
opacity: 0;
}
}
&#13;
<ul>
<li class="light active"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
<li class="light"></li>
</ul>
&#13;