繁体   English   中英

为元素创建功能以停止“setInterval”功能(由另一个元素触发)

[英]creating functionality for element to stop "setInterval" function (triggered by another element)

我创建了一个自动幻灯片 - 在单击“菜单项”后开始。 当单击不同的“菜单项”时,我正在寻找一种“关闭它”的方法。 整个问题可以抽象为一个简单的例子:

为“stop” <li>构建功能(可能会使用stopInterval )。 我想不出解决方案,有人有想法吗?

 const li1 = document.getElementById("li1") li1.addEventListener("click", slideShowAbstract) function slideShowAbstract(e) { const y = setInterval(()=> console.log("playing"), 2000) }
 ul { display: flex; justify-content: center; list-style-type: none; } li { margin: 1rem; } li:hover { cursor: pointer; }
 <ul> <li id="li1">play</li> <li id="li2">stop</li> </ul>

您可以在外部声明y ,以便您可以从多个处理程序访问它。

const li1 = document.getElementById("li1")
const stopElement = document.getElementById("stopButton")
let intervalTimer;

li1.addEventListener("click", slideShowAbstract);
stopElement.addEventListener('click', stopSlideShow);


function slideShowAbstract(e) {
  intervalTimer = setInterval(() => console.log("playing"), 2000);
}

function stopSlideShow(){
  clearInterval(intervalTimer);
}

更好的方法?

为避免全局变量可能受到副作用的影响,请使用一个对象,您可以在其中添加有用的方法。

 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>

界面控制
如果您有 2 个按钮(开始 + 停止),则用户可以在开始按钮上单击 2 次,您最终会得到 2 个重叠的间隔过程(或更多),而无法找到前一个 setInterval 的引用,因为此变量有被替换为引用以下区间的过程

如果没有,您还可以添加一个测试来验证之前没有运行间隔过程。

示例中注释的详细信息

 // Reference both items const li1 = document.getElementById("li1"); const li2 = document.getElementById("li2"); // Bind both items to click event but call different handlers li1.addEventListener("click", start); li2.addEventListener("click", stop); // Declare interval ID let y; // Define time interval let t = 2000; // Define counter let tick = 0; // Define the function to run on each interval const log = () => console.log(t * tick++); // Define the event handler called from li1 function start(e) { // If the tag clicked was #li1 and y isn't defined yet... if (e.target.matches('#li1') && !y) { // ...Initiate interval to call log() y = setInterval(log, t); } } // Define the event handler called from li2 function stop(e) { // If user clicked #li2... if (e.target.matches('#li2')) { // ...Stop interval... clearInterval(y); // ...reset interval ID y = null; } }
 ul { display: flex; justify-content: center; list-style-type: none; } li { margin: 1rem; } li:hover { cursor: pointer; }
 <ul> <li id="li1">play</li> <li id="li2">stop</li> </ul>

 const startBtn = document.getElementById("start") const stopBtn = document.getElementById("stop") const timer = { timerId : undefined, idx : 0, start(){ if(timer.timerId) timer.stop(); timer.timerId = setInterval(()=> { document.getElementById("status").textContent = timer.idx++; console.log(timer.idx); }, 1000); }, stop(){ if(timer.timerId){ clearInterval(timer.timerId); timer.idx = 0; timer.timerId = undefined; document.getElementById("status").textContent = timer.idx; } } } startBtn.addEventListener("click", timer.start); stopBtn.addEventListener("click", timer.stop);
 <button id="start">start</button> <button id="stop">stop</button> <br/> <span id="status"> </span>

暂无
暂无

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

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