[英]Why is my interval calling my function even though its in a variable?
I have a stopwatch that has buttons to start, stop, and reset the time.我有一个秒表,上面有开始、停止和重置时间的按钮。 I assigned an interval to a variable to pause it using clearInterval every time I click the stop button, but my interval is calling the function even though I clicked no button.
每次单击停止按钮时,我都为变量分配了一个间隔以使用 clearInterval 暂停它,但是即使我没有单击任何按钮,我的间隔仍在调用 function。 How do I fix this?
我该如何解决?
const startButton = document.getElementById('start'); const stopButton = document.getElementById('stop'); const resetButton = document.getElementById('reset'); const myInterval = setInterval(setTime, 10); startButton.addEventListener('click', () => { setInterval(setTime, 10); }) stopButton.addEventListener('click', ()=> { clearInterval(myInterval); }) const timeUnits = ['00', '00', '00', '00']; milliSeconds = 0; seconds = 0; minutes = 0; hours = 0; function setTime() { if (minutes == 60) { hours++; minutes = 0; timeUnits[0] = hours; timeUnits[1] = 0; } else if (seconds == 60) { minutes++; seconds = 0; timeUnits[1] = minutes; timeUnits[3] = 0; } else if (milliSeconds == 100) { seconds++; milliSeconds = 0; timeUnits[2] = seconds timeUnits[3] = 0; document.getElementById('para').innerHTML = timeUnits.join(':'); } else { milliSeconds++; timeUnits[3] = milliSeconds; document.getElementById('para').innerHTML = timeUnits.join(':'); }; }
<p id="para">00:00:00:00</p> <button id="start">Start</button> <button id="stop">Stop</button> <button id="reset">Reset</button>
You set up the interval in two places:您在两个地方设置了间隔:
const myInterval = setInterval(setTime, 10); // <-- Here (A)
startButton.addEventListener('click', () => {
setInterval(setTime, 10); // <-- and here (B)
})
In spot A (auto-start on page load) you save the interval ID into myInterval
so that you can later do clearInterval(myInterval)
.在点 A(页面加载时自动启动)中,您将间隔 ID 保存到
myInterval
中,以便以后可以执行clearInterval(myInterval)
。
However, in spot B (on-demand start on "start" button click), you do not do that, so the interval set by clicking the "start" button can never be cleared.但是,在点 B(单击“开始”按钮时按需开始),您不这样做,因此通过单击“开始”按钮设置的间隔永远不会被清除。
This can be fixed by saving the interval into myInterval
in both places:这可以通过在两个地方将时间间隔保存到
myInterval
中来解决:
let myInterval = setInterval(setTime, 10)
startButton.addEventListener('click', () => {
myInterval = setInterval(setTime, 10)
})
Now, this created a bit of duplicate code, which is not ideal, and also there is still the problem that just clicking "start" multiple times would create multiple intervals running in parallel, overwriting the previous interval ID with the new one, making the old intervals again unclearable.现在,这创建了一些重复的代码,这并不理想,并且仍然存在仅单击“开始”多次会创建多个并行运行的间隔的问题,用新的间隔ID覆盖之前的间隔ID,使旧的间隔再次无法清除。
My suggestion for solving both of these issues is to create functions startInterval
and stopInterval
, where startInterval
would also first call stopInterval
before setting up a new interval, and stopInterval
clearing the old one if it exists.我对解决这两个问题的建议是创建函数
startInterval
和stopInterval
,其中startInterval
还会在设置新间隔之前首先调用stopInterval
,如果存在则stopInterval
清除旧间隔。 Then you can call startInterval
both on page load and on "start" button click, and stopInterval
on "stop" button click:然后您可以在页面加载和“开始”按钮单击时
stopInterval
startInterval
,在“停止”按钮单击时调用 stopInterval:
let myInterval = null
function startInterval () {
stopInterval()
myInterval = setInterval(setTime, 10)
}
function stopInterval () {
if (!myInterval) return
clearInterval(myInterval)
myInterval = null
}
startInterval()
startButton.addEventListener('click', startInterval)
stopButton.addEventListener('click', stopInterval)
From the wording of the question I'm not sure whether you really want to auto-start the timer though.从问题的措辞来看,我不确定您是否真的想自动启动计时器。 In case you don't, you can simply remove the
startInterval()
line from my example (or in case of the original code, change the first assignment to let myInterval = null
like in the second example).如果您不这样做,您可以简单地从我的示例中删除
startInterval()
行(或者在原始代码的情况下,将第一个分配更改为let myInterval = null
,就像在第二个示例中一样)。
The reason your interval is automatically starting is because you call the setInterval
function when you assign the variable to begin with.您的间隔自动开始的原因是因为您在分配变量开始时调用了
setInterval
function。 To prevent this, simply define the variable with let myInterval = null;
为了防止这种情况,只需定义变量
let myInterval = null;
so that you get the variable, but it doesn't automatically start the interval until the start button is pressed.这样您就可以获得变量,但在按下开始按钮之前它不会自动开始间隔。
The reason it's not stopping when you press the "stop" button after pressing "start" is because in your startButton
click handler, you're not re-assigning the interval to the variable.按下“开始”后按下“停止”按钮时它没有停止的原因是因为在您的
startButton
单击处理程序中,您没有将间隔重新分配给变量。 So it's an interval that you can't clear because you didn't assign it to anything.所以这是一个你无法清除的间隔,因为你没有将它分配给任何东西。 The simple fix is to say
myInterval = setInterval(setTime, 10)
.简单的解决方法是说
myInterval = setInterval(setTime, 10)
。 Since you are reassigning myInterval
you need to also define it with let
instead of const
.由于您要重新分配
myInterval
,因此您还需要使用let
而不是const
来定义它。
const startButton = document.getElementById('start'); const stopButton = document.getElementById('stop'); const resetButton = document.getElementById('reset'); let myInterval = null; startButton.addEventListener('click', () => { myInterval = setInterval(setTime, 10); }) stopButton.addEventListener('click', ()=> { clearInterval(myInterval); }) const timeUnits = ['00', '00', '00', '00']; milliSeconds = 0; seconds = 0; minutes = 0; hours = 0; function setTime() { if (minutes == 60) { hours++; minutes = 0; timeUnits[0] = hours; timeUnits[1] = 0; } else if (seconds == 60) { minutes++; seconds = 0; timeUnits[1] = minutes; timeUnits[3] = 0; } else if (milliSeconds == 100) { seconds++; milliSeconds = 0; timeUnits[2] = seconds timeUnits[3] = 0; document.getElementById('para').innerHTML = timeUnits.join(':'); } else { milliSeconds++; timeUnits[3] = milliSeconds; document.getElementById('para').innerHTML = timeUnits.join(':'); }; }
<p id="para">00:00:00:00</p> <button id="start">Start</button> <button id="stop">Stop</button> <button id="reset">Reset</button>
This line:这一行:
const myInterval = setInterval(setTime, 10);
actually starts the interval.实际上开始了间隔。
You need to change it to this:您需要将其更改为:
let myInterval;
startButton.addEventListener('click', () => {
myInterval = setInterval(setTime, 10);
})
This ensures that everytime you press the start
button the interval will be assigned to the myInterval
variable again which can then be cleared by the stop button这样可以确保每次按下
start
按钮时,间隔将再次分配给myInterval
变量,然后可以通过停止按钮将其清除
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.