如何将 class 添加到纯 javascript 中的随机元素
How to add class to random element in pure javascript
我有一个 ul,里面有一些 li
。
我想随机 select 一个 li
并添加一个 .active
class 1 秒,然后删除 .active
class 并随机 select下一个 li
。
我试图在不使用 setInterval 或 Timeout 的情况下执行此操作,因此我尝试使用 requestAnimationFrame,尽管我认为我使用 javascript 的逻辑在随机化方面不太正确。
目前我可以使用它,但是每次再次调用该函数时,它 select 都是一样的 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
提前致谢!
运行 未来或多或少已知时间的函数的正确选择是 setTimeout
。 requestAnimationFrame
用于在不中断渲染循环的情况下应尽可能频繁地 运行 的东西,比如每秒 60 次(又名 "at 60 fps")。
在您的情况下,您的更新速度相对较慢,为每秒一次,因此 setTimeout
没有什么坏处。
您可能想要跟踪两个元素:一个是您正在更改的元素,另一个是您之前更改过的元素,以便您可以重置它。
此外,classList.toggle
会派上用场,因为它会根据 class 是否已经存在来添加或删除它。
(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 是更新后的(略有改动的)笔。
您需要更新每次函数运行时要闪烁的灯。要每秒进行不同的灯光变化,请检查动画帧时间是否为一秒。
(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);
})();
li {
background: 1px black
}
li.active {
animation: blink 1s ease-in-out infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<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>
I am trying to do this without the use of setInterval or Timeout
您可以使用 animationend
事件在当前 CSS 动画完成时调用相同的函数
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)
.light.active {
animation: blink 1s ease-in-out;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<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>
我有一个 ul,里面有一些 li
。
我想随机 select 一个 li
并添加一个 .active
class 1 秒,然后删除 .active
class 并随机 select下一个 li
。
我试图在不使用 setInterval 或 Timeout 的情况下执行此操作,因此我尝试使用 requestAnimationFrame,尽管我认为我使用 javascript 的逻辑在随机化方面不太正确。
目前我可以使用它,但是每次再次调用该函数时,它 select 都是一样的 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
提前致谢!
运行 未来或多或少已知时间的函数的正确选择是 setTimeout
。 requestAnimationFrame
用于在不中断渲染循环的情况下应尽可能频繁地 运行 的东西,比如每秒 60 次(又名 "at 60 fps")。
在您的情况下,您的更新速度相对较慢,为每秒一次,因此 setTimeout
没有什么坏处。
您可能想要跟踪两个元素:一个是您正在更改的元素,另一个是您之前更改过的元素,以便您可以重置它。
此外,classList.toggle
会派上用场,因为它会根据 class 是否已经存在来添加或删除它。
(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 是更新后的(略有改动的)笔。
您需要更新每次函数运行时要闪烁的灯。要每秒进行不同的灯光变化,请检查动画帧时间是否为一秒。
(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);
})();
li {
background: 1px black
}
li.active {
animation: blink 1s ease-in-out infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<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>
I am trying to do this without the use of setInterval or Timeout
您可以使用 animationend
事件在当前 CSS 动画完成时调用相同的函数
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)
.light.active {
animation: blink 1s ease-in-out;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<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>