需求: 用js實現紅綠燈效果。
三個狀態用紅(stop)、綠(pass)、黃(wait)
要求用JavaScript讓三個狀態輪流切換,每個狀態停留2s
HTML
<ul id="traffic" class="stop" >
<li><span></span></li>
<li><span></span></li>
<li><span></span></li>
</ul>
CSS
li{
list-style: none;
}
ul li span{
display: inline-block;
width: 50px;
height: 50px;
background-color: gray;
margin: 5px;
border-radius: 50%;
}
#traffic.stop li:nth-child(1) span{
background-color: red;
}
#traffic.wait li:nth-child(2) span{
background-color: yellow;
}
#traffic.pass li:nth-child(3) span{
background-color: green;
}
JavaScript實現
版本1
缺點:依賴外部變量stataList,currentIndex, 封裝性差了點
const traffic = document.getElementById('traffic');
const statusList = ['stop', 'wait', 'pass'];
var curentIndex=0;
setInterval(() => {
let state = statusList[curentIndex];
traffic.className = state;
curentIndex = (curentIndex+1) % statusList.length;
}, 2000);
版本2 數據抽象
缺點:比版本1好點,不過擴展性較差
const traffic = document.getElementById('traffic');
const stateArr = ['stop', 'wait', 'pass'];
function trafficFn(trafficDom, stateList){
let currentIndex = 0;
setInterval( ()=>{
const state = stateList[currentIndex];
trafficDom.className = state;
currentIndex = (currentIndex+1) % stateList.length;
}, 2000 )
}
trafficFn( traffic, stateArr );
版本3 函數式編程, 抽象出poll方法
const traffic = document.getElementById('traffic');
// const statusList = ['stop', 'wait', 'pass'];
function poll(...fnList){
let stateInex = 0;
return function(...args){
let fn = fnList[stateInex++ % fnList.length];
return fn.apply(this, args);
}
}
function setState(state){
traffic.className = state;
}
// 循環執行這三個函數
let trafficStatePoll = poll(
setState.bind(null, 'wait'),
setState.bind(null, 'stop'),
setState.bind(null, 'pass')
)
setInterval(trafficStatePoll, 2000);