为什么这个 while 循环不会 运行?
Why will this while-loop not run?
我正在尝试学习 Javascript 中的 while 循环。为什么这个 while 循环 运行 即使单击按钮并且布尔值变为真?甚至可以让 while 循环对事件驱动的变量变化做出反应吗?
let run = false;
let count = 0;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
})
while (run == true) {
count++;
counter.innerHTML = count;
}
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
循环没有执行,因为运行为假。
这里我们可以将 while 移到按钮上,但这不会起作用,因为紧密循环没有给 DOM 时间来更新。
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
while (run) {
count++;
counter.innerHTML = count;
}
})
我完全不建议使用 while 循环来更新 DOM
这会起作用,但即使不更新计数器,循环也会运行
let run = false;
let count = 0;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
})
setInterval(function() {
if (!run) return
count++;
counter.innerHTML = count;
},10)
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
更优雅的版本是 clearInterval
let run = false;
let count = 0;
let tId;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
if (run) tId = setInterval(function() {
count++;
counter.innerHTML = count;
}, 10)
else clearInterval(tId)
})
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
while 是 运行 但是当页面加载时,所以当您单击按钮时 while 循环已经通过。当您将 while 循环放在点击侦听器中时,您可以看到这一点,但这不是您想要的行为。而是使用间隔来解决此问题,如下所示:
let run = false;
let count = 0;
let interval = null;
const delay = 100;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
if (run === true) {
interval = setInterval(() => {
count++;
counter.innerHTML = count;
}, delay)
} else {
clearInterval(interval)
}
})
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
当您启动页面时,while 循环实际上是第一次结束。切换布尔值时,它不会自动为您重新呈现 dom。所以如果你想 运行 while 循环,你需要将它包装在一个函数中并调用它。
PS 运行 顺便说一下,此代码会冻结您的浏览器。尝试添加延迟
let run = false;
let count = 0;
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
doRun();
})
const doRun = () => {
while (run) {
count++;
counter.innerHTML = count;
}
}
doRun()
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
检查 while (run == true) {
在添加事件侦听器后立即发生,此时 run
的值仍然是 false
。
此外,永不停止的 while 循环将完全淹没线程,使用户无法单击按钮。
您可以使用 setInterval
,它每 x 毫秒运行一个函数。
这样,您可以随时检查 run
的值,而不会阻塞线程(这是 while (run == true) {
所做的)。
let run = false;
let count = 0;
let intervalID = setInterval(tick, 1000); // 1000ms = 1sec
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
button.textContent = run ? "Stop" : "Start";
});
function tick() {
if (run) {
count++;
counter.innerHTML = count;
}
}
<button id="startstop">Start</button>
<p id="counter">0</p>
这样做的问题是,每次重新启动计时器时,您可能会关闭将近一整秒。要改进时间测量,您可以改为使用变量 count
来存储计数器打开时实际经过的毫秒数。使用另一个变量来存储最后一次测量发生的时间戳(或最后一次单击开始按钮的时间)也会大大提高准确性。
let run = false;
let count = 0;
let previousTick = Date.now();
let intervalID = setInterval(tick, 100); // 100ms = 0.1sec
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
button.textContent = run ? "Stop" : "Start";
previousTick = Date.now();
});
function tick() {
if (run) {
count += Date.now() - previousTick;
counter.innerHTML = Math.floor(count / 1000);
previousTick = Date.now();
}
}
<button id="startstop">Start</button>
<p id="counter">0</p>
我正在尝试学习 Javascript 中的 while 循环。为什么这个 while 循环 运行 即使单击按钮并且布尔值变为真?甚至可以让 while 循环对事件驱动的变量变化做出反应吗?
let run = false;
let count = 0;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
})
while (run == true) {
count++;
counter.innerHTML = count;
}
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
循环没有执行,因为运行为假。
这里我们可以将 while 移到按钮上,但这不会起作用,因为紧密循环没有给 DOM 时间来更新。
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
while (run) {
count++;
counter.innerHTML = count;
}
})
我完全不建议使用 while 循环来更新 DOM
这会起作用,但即使不更新计数器,循环也会运行
let run = false;
let count = 0;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
})
setInterval(function() {
if (!run) return
count++;
counter.innerHTML = count;
},10)
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
更优雅的版本是 clearInterval
let run = false;
let count = 0;
let tId;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
if (run) tId = setInterval(function() {
count++;
counter.innerHTML = count;
}, 10)
else clearInterval(tId)
})
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
while 是 运行 但是当页面加载时,所以当您单击按钮时 while 循环已经通过。当您将 while 循环放在点击侦听器中时,您可以看到这一点,但这不是您想要的行为。而是使用间隔来解决此问题,如下所示:
let run = false;
let count = 0;
let interval = null;
const delay = 100;
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
if (run === true) {
interval = setInterval(() => {
count++;
counter.innerHTML = count;
}, delay)
} else {
clearInterval(interval)
}
})
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
当您启动页面时,while 循环实际上是第一次结束。切换布尔值时,它不会自动为您重新呈现 dom。所以如果你想 运行 while 循环,你需要将它包装在一个函数中并调用它。
PS 运行 顺便说一下,此代码会冻结您的浏览器。尝试添加延迟
let run = false;
let count = 0;
button.addEventListener('click', function() {
run = !run; //clever way to toggle the boolean
doRun();
})
const doRun = () => {
while (run) {
count++;
counter.innerHTML = count;
}
}
doRun()
<button id="startstop">Start/Stop</button>
<p id="counter">0</p>
检查 while (run == true) {
在添加事件侦听器后立即发生,此时 run
的值仍然是 false
。
此外,永不停止的 while 循环将完全淹没线程,使用户无法单击按钮。
您可以使用 setInterval
,它每 x 毫秒运行一个函数。
这样,您可以随时检查 run
的值,而不会阻塞线程(这是 while (run == true) {
所做的)。
let run = false;
let count = 0;
let intervalID = setInterval(tick, 1000); // 1000ms = 1sec
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
button.textContent = run ? "Stop" : "Start";
});
function tick() {
if (run) {
count++;
counter.innerHTML = count;
}
}
<button id="startstop">Start</button>
<p id="counter">0</p>
这样做的问题是,每次重新启动计时器时,您可能会关闭将近一整秒。要改进时间测量,您可以改为使用变量 count
来存储计数器打开时实际经过的毫秒数。使用另一个变量来存储最后一次测量发生的时间戳(或最后一次单击开始按钮的时间)也会大大提高准确性。
let run = false;
let count = 0;
let previousTick = Date.now();
let intervalID = setInterval(tick, 100); // 100ms = 0.1sec
const button = document.getElementById("startstop");
const counter = document.getElementById("counter");
button.addEventListener('click', function() {
run = !run;
button.textContent = run ? "Stop" : "Start";
previousTick = Date.now();
});
function tick() {
if (run) {
count += Date.now() - previousTick;
counter.innerHTML = Math.floor(count / 1000);
previousTick = Date.now();
}
}
<button id="startstop">Start</button>
<p id="counter">0</p>