2017-09-29 53 views
0

我有一個ul,裏面有一些li。 我想隨機選擇一個li並添加一個.active類爲1秒,然後刪除.active類和隨機選擇下一個li如何在純javascript中添加隨機元素的類

我想這樣做,而不使用setInterval或超時,所以我嘗試過使用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

爲什麼你試圖避免'setInterval()'? –

+0

你永遠不會開始運行'repeatOften()'函數。所以它不會重複設置'active'類,它只是將它應用於第一種情況。 – Adjit

+0

@AlexeySoshin避免佈局抖動,延遲間隔不一致,如果用戶更改標籤,它會影響計時。從我讀的requestAnimationFrame是要走的路,我試圖讓自己熟悉:) – h0bb5

回答

0

在未來或多或少已知時間運行某個功能的正確選擇是setTimeout。​​是指應該在不中斷渲染循環的情況下儘可能經常運行,例如每秒60次(又稱「60 fps」)。

在你的情況下,你有一個比較慢的更新速度每秒一次,所以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

投票正確,因爲它是我的問題的最佳實踐解決方案,即使它沒有使用RequestAnimationFrame。斯文下面的答案是我所尋找的,但不是這類問題的正確解決方案。 – h0bb5

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

0

我試圖做到這一點,而不使用的setInterval或超時

您可以使用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>

相關問題