js中秒表无法使用清除间隔方法

Posted

技术标签:

【中文标题】js中秒表无法使用清除间隔方法【英文标题】:Failing to use clear interval method for a stopwatch in js 【发布时间】:2021-12-15 14:41:11 【问题描述】:

我正在尝试为正在运行的游戏创建秒表(在单击第一张卡片时开始,在所有卡片打开时停止),并且与 setInterval 应该正常工作不同,我无法让 clearInterval 工作。

var elPrevCard = null;
var flippedCards = 0;
let elNewGameBtn = document.querySelector('.new-game');
let elAllCards = document.querySelectorAll('.card');
var TOTAL_COUPLES_COUNT = 3;

let elStopwatch = document.querySelector('.stopwatch');
let ms = 0;
let sec = 0;
let min = 0;
let time;

function stopwatchTime() 
    ms++;
    if (ms >= 100) 
        sec++;
        ms = 0;
    
    
    if (sec === 60) 
        min++;
        sec = 0;
    
    
    if (min === 60) 
        ms, sec, min = 0;
    
    
    let millis = ms < 10 ? `0` + ms : ms;
    let seconds = sec < 10 ? `0` + sec : sec;
    let minute = min < 10 ? `0` + min : min;
    
    let timer = `$minute:$seconds:$millis`;
    elStopwatch.innerhtml = timer;
;

function startStopwatch() 
    time = setInterval(stopwatchTime, 10);


function stopStopwatch() 
    clearInterval(time);


function resetStopwatch() 
    ms = 0;
    sec = 0;
    min = 0;
    
    elStopwatch.innerHTML = `00:00:00`;



for (let i = 0; i < elAllCards.length; i++) 
    elAllCards[i].addEventListener('click', startStopwatch();
    );


function cardClick(elCard) 
    elCard.classList.add('flipped');
    
    if (elPrevCard === null) 
        elPrevCard = elCard;
     else 
        var card1 = elPrevCard.getAttribute('data-card');
        var card2 = elCard.getAttribute('data-card');
        
        if (card1 !== card2) 
            setTimeout(function() 
                elCard.classList.remove('flipped');
                elPrevCard.classList.remove('flipped');
                elPrevCard = null;
            , 1000);
            
         else 
            flippedCards++;
            elPrevCard = null;
            
            if (TOTAL_COUPLES_COUNT === flippedCards) 
                stopStopwatch();

                elNewGameBtn.style.display = 'inline';
            
        
    


elNewGameBtn.addEventListener('click', function newGame() 
    for (let i = 0; i < elAllCards.length; i++) 
        elAllCards[i].classList.remove('flipped');
    
    
    flippedCards = 0;
    elNewGameBtn.style.display = 'none';
    resetStopwatch();
);

非常感谢您的帮助,我不知道我在这里缺少什么。

提前感谢所有帮助者!

【问题讨论】:

您已经为每张卡片添加了一个监听器以启动秒表,因此在每次卡片点击时,都会设置一个新的间隔并覆盖time 变量,因此停止函数只会清除最后一个设置间隔。 @pilchard 这是有道理的,但是考虑到我无法判断用户将点击哪张卡片,我怎样才能让它在点击第一张卡片时开始计时?谢谢沙丁鱼 @pilchard 我试图放置一个 controller.abort();在 startStopWatch() 之后;虽然它现在停止秒表,但点击新游戏后,秒表不会再次启动。我不知道如何重置它 【参考方案1】:

您可以简单地检查time当前是否持有一个值,并在清除间隔时将其设置为null

注意:另外,在添加监听器时,一定要传递函数而不是调用它。所以card.addEventListener('click', startStopwatch); 不是card.addEventListener('click', startStopwatch());

let time = null;

// ...

function startStopwatch() 
  if (time === null) 
    time = setInterval(stopwatchTime, 10);
  


function stopStopwatch() 
  if (time !== null) 
    clearInterval(time);
    time = null;
  


//...

for (const card of elAllCards) 
  card.addEventListener('click', startStopwatch);

【讨论】:

以上是关于js中秒表无法使用清除间隔方法的主要内容,如果未能解决你的问题,请参考以下文章

无法在异步间隔中清除计时器

秒表与计时器 - 何时使用

无法使用pyqt5显示秒表

使用 redux 创建秒表

谈谈垃圾回收机制方式内存管理?

tailwind.config.js 清除选项无法识别 PHP 文件并导致无限重新编译