更好的方法?
要避免全局变量会受到副作用的影响,请使用对象,您可以向其中添加有用的方法.
const
btPlay = document.querySelector('#bt-play')
, player = (()=> // IIFE for object { play(), stop() } method
{
let // inside Object values ( closure )
refIntv = 0
, counter = 0
, onProcess = false // security to avoid multiple setInterval processes
;
function playerAction() // inside private function
{
console.clear()
console.log( 'playing', ++counter)
}
return {
play()
{
if (onProcess) return // security to avoid doing setInterval() twice
onProcess = true
counter = 0
console.clear()
console.log('start playing')
refIntv = setInterval( playerAction , 2000)
}
, stop()
{
if (!onProcess) return // security to avoid doing clearInterval() twice
clearInterval( refIntv )
onProcess = false
console.clear()
console.log('stop playing')
}
}
})();
btPlay.onclick =_=>
{
if (btPlay.classList.toggle('stopped')) player.play()
else player.stop()
}
button {
margin : 1em 3em;
width : 5em;
}
#bt-play::after {
content : 'play';
}
#bt-play.stopped::after {
content : 'stop';
}
<h5> case 1: same button for start and stop </h5>
<button id="bt-play"></button>
<!-- control by interface : same button for start and stop -->
<hr>
<h5> case 2: 2 buttons </h5>
<button onclick="player.play()">play</button>
<button onclick="player.stop()">stop</button>
interface control:
if you have 2 buttons (start + stop), the user can click 2 times on the start button and you
you end up with 2 overlapping interval processes (or more) without the possibility of finding the reference of the previous setInterval since this variable has been replaced to reference the process of the following interval
如果没有,您还可以添加一个测试,验证之前没有运行间隔进程.