我有一个从1到20的简单循环。我想做的是使用按钮单击来停止循环。我所做的是,我设置了一个条件,即单击按钮时,变量stop
的值将更改为1,这将触发break
。但是该值不会更改。
var stop = 0;
for(let i = 1; i <= 20; i++){
if(stop === 1){
break;
}
setTimeout(function(){
$('ul').append('<li>'+ i +'</li>');
},i * 500);
}
$('button').click(function(){
stop = 1;
});
ul li{
list-style-type: none;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
答案 0 :(得分:4)
在您甚至按下停止键之前,已经调用了20个setTimeout
函数。
解决此问题的多种方法之一是检查函数stop
中正在执行的setTimeout
变量。
var stop = 0;
for (let i = 1; i <= 20; i++){
setTimeout(function(){
console.log(stop);
if (stop !== 1) {
$('ul').append('<li>'+ i +'</li>');
}
},i * 500);
}
$('button').click(function(){
stop = 1;
});
ul li{
list-style-type: none;
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
修改:
您问如何停止for
循环。书写方式不可能。
这就是我为了通过setTimeout
“停止”循环而实现的方式。
您也可以使用setInterval
(检查Сергей Петрашко's answer来了解如何操作)。
了解它们之间的区别here):
var stop = false;
function addNumberAndCallNext(number, max) {
if (!stop && number <= max) {
$('ul').append('<li>'+ number +'</li>');
setTimeout(addNumberAndCallNext.bind(null, ++number, max), 500);
}
}
addNumberAndCallNext(1, 20);
$('button').click(function(){
stop = true;
});
ul li {
list-style-type: none;
float: left;
padding-right: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>
答案 1 :(得分:2)
您可以在没有jQuery的情况下尝试下一个代码。
我不建议您使用--- $('ul').append('<li>'+ i +'</li>');
-
是坏习惯。
正确的方法-是在循环前创建节点。
在此任务中,您可以使用setIntrval代替setTimout并循环
let itemList = (i) => {
let item = document.createElement('li');
item.value = i;
item.textContent = i;
return item;
}
let list = document.getElementById('list');
let stopButton = document.getElementById('stop');
let i = 0,
interval;
let reset = () => {
clearInterval(interval)
}
stopButton.addEventListener('click', () => {
reset()
});
interval = setInterval(() => {
list.append(itemList(i))
i++;
if (i > 20) reset()
}, 300)
<button id="stop">stop</button>
<br>
<ul id="list"></ul>
答案 2 :(得分:2)
您无法通过click事件停止for循环,因为JavaScript是单线程的。循环开始
for(let i = 1; i <= 20; i++){
...
在执行时同步运行,而不会被事件处理程序中断。。
它将启动20个计时器调用,相隔500毫秒执行一次,并在单击处理程序执行之前返回事件循环。
您可以选择启动计时器调用,并在添加元素之前检查停止标志,或者设置某种异步循环(例如,使用setInterval
)来递增i
变量并停止如果i
达到最大值或发生点击事件,则计时器回调。
答案 3 :(得分:1)
问题是整个for循环在您甚至没有机会按下按钮之前就已执行。 setTimeout实际上并不会休眠或阻塞,而是放置一个新事件,然后继续在for循环中进行。
浏览器,用于超时目的的所有时钟等等只能在代码暂时完成运行时运行。没有东西等同于sleep()函数。
也许使用异步功能(ES2015 IIRC,当前所有非IE浏览器都应支持),并且等待util.promisify(setTimeout)(2000)
创建的承诺会更加直观。
没有阻止功能。代码内部没有休眠。所有代码基本上都在CPU上运行,并设置I / O和计时器事件,一旦同步部分已经完成,它们将异步发生。
由于这个原因,JavaScript不直观。但是,一旦看到以这种方式可以获得一种性能,您可能会感到异步的价值。我的意思是...当JS代码本身正在执行DOM时,浏览器无法检查。您无法滚动,无法单击,鼠标光标本身也不会改变其种类。只有在代码块完成后,浏览器才会处理所有未决事件。
答案 4 :(得分:1)
我将递归执行此操作。然后您有两个休息条件,停止并计数===最大值。
var stop = false;
var print = function(count, max) {
setTimeout(function(){
if(stop){
return;
}else if(count === max){
return;
}else{
$('ul').append('<li>'+ count +'</li>');
return print(++count, max);
}
}, 500);
}
$('button').click(function(){
stop = true;
});
print(0, 20);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>stop</button>