JavaScript中计时器自动启动而不是在按钮按下时启动

3

我对JavaScript还比较陌生,所以答案可能很简单,但无论如何

我试图制作一个简单的点击速度测试,但我无法在用户按下“点击我”按钮时启动计时器,因此我只能自动启动它。如果有人能帮我实现在按钮按下时启动计时器,将不胜感激。

HTML代码:

<button id="click2" onclick="click2()">Click Me!</button><br>
<span id="clicksamount">0 Clicks</span><br><br>
<span id="10stimer">10s</span>

JS 代码:

var click = document.getElementById("click2");
var amount = 0;

var seconds = 10;
var endOfTimer = setInterval(click2, 1000);

function click2() {
    seconds--;
    document.getElementById("10stimer").innerHTML = seconds + "s";
    if (seconds <= 0) {
        var cps = Number(amount) / 10;
        document.getElementById("clicksamount").innerHTML = "You got " + cps + " CPS!";
        document.getElementById("click2").disabled = true;
        document.getElementById("10stimer").innerHTML = "Ended";
        clearInterval(seconds);
    }
}
document.getElementById("click2").onclick = function() {
    amount++;
    document.getElementById("clicksamount").innerHTML = amount + " Clicks";
}

setInterval(click2, 1000); 移动到 onclick 函数中。 - Stephen S
每次点击都会创建一个新的间隔。 - SoWhat
4个回答

2
看起来你正在用最后四行代码覆盖带有id click2的按钮上的onclick函数。
此外,你使用秒数变量而不是实际间隔调用clearInterval()函数,该间隔由endOfTimer引用。
我建议将定时器管理单独放在一个函数中,仅在按钮第一次点击时调用该函数。 查看JSFiddle
<button id="clickbutton" onclick="buttonClick()">Click Me!</button><br>
<span id="clicksamount">0 Clicks</span><br><br>
<span id="secondcount">10s</span>

// We will have timerStarted to see if the timer was started once, 
// regardless if it's still running or has already ended. Otherwise
// we would directly restart the timer with another click after the 
// previous timer has ended.
// timerRunning only indicates wether the timer is currently running or not.
var timerStarted = false;
var timerRunning = false;
var seconds = 10;
var clickAmount = 0;
var timer;

function buttonClick() {
  if (!timerStarted) {
    startTimer();
  }
  // Only count up while the timer is running.
  // The button is being disabled at the end, therefore this logic is only nice-to-have.
  if (timerRunning) {
    clickAmount++;
    document.getElementById("clicksamount").innerHTML = clickAmount + " Clicks";
  }
}

function startTimer() {
  timerStarted = true;
  timerRunning = true;
  timer = setInterval(timerTick,1000);
}

function timerTick() {
  seconds--;
  document.getElementById("secondcount").innerHTML = seconds + "s";
  if (seconds <= 0) {
    timerRunning = false;
    clearInterval(timer);
    var cps = Number(clickAmount) / 10;
    document.getElementById("clickbutton").disabled = true;
    document.getElementById("clicksamount").innerHTML = "You got " + cps + " CPS (" + clickAmount + "clicks in total)!";
  }
}


1
我以相同的方式重写了 :P - SoWhat
1
你比我快了几秒钟 :) - sumit
@sumit 我不经常上SO,也很少写答案,但这一次我知道我可以帮助并为你带来好处 :-D - Florian Müller

0

我对你的代码进行了一些更改。实际上,当用户第一次点击时,您开始计时器。直到用户第一次点击之前,计时器变量为null。

var click = document.getElementById("click2");
var noOfClicks = 0;
var seconds = 10;
var timer  = null;

function doTick(){
  seconds--;
  if(seconds<=0){
    seconds = 10;
    clearInterval(timer);
    document.getElementById("10stimer").innerHTML= "Ended"
    timer=null;
    document.getElementById("click2").disabled = true;

  }
  updateDisplay()
}

function updateClicks(){
if(!timer){
  timer=setInterval(doTick, 1000);
  clicks= 0;
  seconds = 10;

}
  noOfClicks++;

  updateDisplay();
}

function updateDisplay(){
      var cps = Number(noOfClicks) / 10;

      document.getElementById("clicksamount").innerHTML = "You got " + cps + " CPS!";
    document.getElementById("10stimer").innerHTML =seconds;


}
click.addEventListener('click', updateClicks)

https://jsbin.com/bibuzadasu/1/edit?html,js,console,output


0
function timer(startEvent, stopEvent) {
    let time = 0;
    startEvent.target.addEventListener(startEvent.type, () => {
        this.interval = setInterval(()=>{
            time++;
        }, 10); // every 10 ms... aka 0.01s

        removeEventListener(startEvent.type, startEvent.target); // remove the listener once we're done with it.

        stopEvent.target.addEventListener(startEvent.type, () => {
            clearInterval(this.interval); // stop the timer

            // your output function here, example:
            alert(time);

            removeEventListener(stopEvent.type, stopEvent.target); // remove the listener once we're done with it.
        });
    });

}

使用事件监听器而不是onclicks

用法示例:

HTML

<button id="mybutton">Click me!</button>

JS

/* ABOVE CODE ... */
let mybutton = document.getElementById("mybutton");
timer(
    {target: mybutton, type: "click"},
    {target: mybutton, type: "click"}
);

function timer(startEvent, stopEvent) {
     let time = 0;
     startEvent.target.addEventListener(startEvent.type, () => {
      this.interval = setInterval(()=>{
       time++;
      }, 10); // every 10 ms... aka 0.01s

      removeEventListener(startEvent.type, startEvent.target); // remove the listener once we're done with it.

      stopEvent.target.addEventListener(startEvent.type, () => {
       clearInterval(this.interval); // stop the timer

       // your output function here, example:
       alert(time);
   
       removeEventListener(stopEvent.type, stopEvent.target); // remove the listener once we're done with it.
      });
        });
 
    }

    let mybutton = document.getElementById("mybutton");
    timer(
        {target: mybutton, type: "click"},
        {target: mybutton, type: "click"}
    );
<button id="mybutton">Click me!</button>


0
//state initialization
var amount = 0;
var seconds = 10;
var timedOut=false;
var  timerId=-1;
//counters display
var clicksDisplay= document.getElementById("clicksamount");
var timerDisplay= document.getElementById("10stimer");
function click2(e){
  //first click 
  if(timerId===-1){
      //start timer  
     timed();
  }
  //still in time to count clicks
 if(!timedOut){
    amount++;
  clicksDisplay.innerText=amount +" Clicks";
 }

}
function timed(){
  //refresh timer dispaly
   timerDisplay.innerText=seconds+"s";
  seconds--;

  if(seconds<0){
    //stop click count
    timedOut=true;    
  }else{
    //new timerId
  timerId=setTimeout(timed,1000);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接