简体   繁体   English

如何在纯javascript中将类添加到随机元素

[英]How to add class to random element in pure javascript

I have a ul with some li 's inside. 我里面有些li I want to randomly select an li and add an .active class for 1second, then remove .active class and randomly select a next li . 我想随机选择一个li并添加一个.active类1 .active ,然后删除.active类并随机选择下一个li

I am trying to do this without the use of setInterval or Timeout, so I have tried using requestAnimationFrame although I think my logic with javascript is not quite right on randomizing. 我试图在不使用setInterval或Timeout的情况下执行此操作,因此尽管我认为使用javascript的逻辑在随机化方面不太正确,但我尝试使用requestAnimationFrame。

Currently I have it working but it selects the same li each time the function is called again. 目前,我可以使用它,但是每次再次调用该函数时,它都会选择相同的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 Java脚本

(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);

})();

Here is a pen: https://codepen.io/H0BB5/pen/PJjapX?editors=0010 这是一支钢笔: https : //codepen.io/H0BB5/pen/PJjapX?editors=0010

Thanks in advance! 提前致谢!

The right choice to run a function in a more-or-less known time in the future is setTimeout . setTimeout是在将来或多或少已知时间运行函数的正确选择。 requestAnimationFrame is meant for something that should run as often as is feasible without interrupting the render loop, say 60 times a second (aka "at 60 fps"). requestAnimationFrame的意思是应该尽可能在不中断渲染循环的情况下运行,例如每秒60次(又称为“ 60 fps”)。

In your case you have a relatively slow update rate of once a second, so setTimeout isn't hurting. 在您的情况下,您的每秒更新速度相对较慢,因此setTimeout不会受到影响。

You probably want to keep track of two elements: The one you're changing and the one you previously changed, so you can reset it. 您可能希望跟踪两个元素:要更改的元素和以前更改的元素,因此可以对其进行重置。

Also, classList.toggle comes in handy as it adds or removes a class, based on if it's already present or not. 同样, 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 is the updated (and slightly changed) pen. 是更新(并稍有更改)的笔。

You need to update which light to blink every time the function runs. 您需要在每次该功能运行时更新哪个指示灯闪烁。 To make a different light change every second, check if the animation frame time has been a second. 要每秒更改一次不同的灯光,请检查动画帧时间是否为一秒钟。

 (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 我正在尝试不使用setInterval或Timeout来执行此操作

You can use animationend event to call same function when current CSS animation completes 当前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) 
 .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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM