使用点击中断停止循环

时间:2018-08-30 08:03:03

标签: javascript jquery for-loop break

我有一个从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>

5 个答案:

答案 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>