javascript 多次或重置倒计时功能

javascript Multiple or Reset countdown function

我想在每次单击开始时重置 javascript 中的倒数计时器。如果倒计时结束就没问题,但如果倒计时还在继续,然后我再次点击开始,它会在同一个地方显示 2 个倒计时(不重置)

enter link description here 这是代码

function countdown( elementName, minute, second )
{
   var element, endTime, hours, mins, msLeft, time ;

    function twoDigits( n )
    {
        return (n <= 9 ? "0" + n : n);
    }

    function updateTimer()
    {
        msLeft = endTime - (+new Date);
        if ( msLeft < 1000 ) {
            element.innerHTML = "Alarm";
        } else {
            time = new Date( msLeft );
            hours = time.getUTCHours();
            mins = time.getUTCMinutes();
            element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
            setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
        }
    }

    element = document.getElementById( elementName );
    endTime = (+new Date) + 1000 * (60*minute + second) + 500;
    updateTimer();
 //if ( abort == 999 ){msLeft = 0 ;}
}

function resetz(a) {
 if(a==11){countdown( "demo", 0, 10 )}
 if(a==21){countdown( "demo2", 5, 0 )}
}
div {
    /* text-align: center; */
    border: 5px solid #004853;
    display:inline;
    padding: 5px;
    color: #004853;
    font-family: Verdana, sans-serif, Arial;
    font-size: 40px;
    font-weight: bold;
    text-decoration: none;
}

body {
  padding: 20px;
  text-align: center;
}
.btn {
  font-size: 19px;
  position: relative;
  width: 100%;
  background: #004853;
  color: #fff;
  border-radius: .55em;
  transition: all 0.35s ease;
  overflow: hidden;
  border-top: 1px solid rgba(0, 0, 0, 0.2);
  padding: 5px;
  text-align: center;
  cursor : pointer;
}
<div id="demo" >00:00</div>
<a class="btn" onclick="resetz(11)">START</a> 
<div id="demo2" >00:00</div>
<a class="btn" onclick="resetz(21)">START</a> 

如果您重置计数器,您可以记住 setTimeout 的句柄并取消它:
为此,您可以声明一个全局数组 timer[],它为每个计时器保存超时句柄(如果已声明)。当你开始倒计时时,你会看看是否有这个计时器的存储句柄,如果有,取消它的超时。当您开始超时时,您必须记住计时器数组中的句柄,以便稍后可以停止它。在您的 resetz 函数中,您需要另一个参数作为计时器的 nr,因此您在更新函数中知道处理了哪个计时器。 这是代码:https://jsfiddle.net/wxt4dbyo/1/

var timer = [];

function countdown( elementName, minute, second, nr )
{
  if ( timer[nr] ) clearTimeout( timer[nr] );
  var element, endTime, hours, mins, msLeft, time ;

  function twoDigits( n )
  {
    return (n <= 9 ? "0" + n : n);
  }

  function updateTimer()
  {
    msLeft = endTime - (+new Date);
    if ( msLeft < 1000 ) {
        element.innerHTML = "Alarm";
    } else {
        time = new Date( msLeft );
        hours = time.getUTCHours();
        mins = time.getUTCMinutes();
        element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
        timer[nr] = setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
    }
  }

  element = document.getElementById( elementName );
  endTime = (+new Date) + 1000 * (60*minute + second) + 500;
  updateTimer();
}

function resetz(a) {
  if(a==11){countdown( "demo", 0, 10, 1 )}
  if(a==21){countdown( "demo2", 5, 0, 2 )}
}

我知道这不是一个完美的解决方案,但它确实有效。我建议您使用 setInterval 而不是 setTimeout,这样您就可以解决无休止递归的问题。现在,您的计时器会随着每次递归而构建堆栈,并且对于一些更大的时间值,您可能会出现内存泄漏。为此,您必须更改更多代码。