Изменить продолжительность setTimeout по клику - PullRequest
0 голосов
/ 31 августа 2018

Я работаю над этим простым циклом, который отображает 1-20 чисел. Он отображался один за другим с интервалом в 500 мс. то, что я пытаюсь сделать, это когда цикл включен на 10, а затем я нажимаю кнопку, она мгновенно покажет оставшиеся 10 чисел.

Спасибо.

var duration = 500;
for(let i=0; i < 20; i++ ){
  setTimeout(function(){
     $('ul').append('<li>'+ (i+1) +'</li>')
  }, i * duration);
}

$('button').click(function(){
   duration = 0;
});
ul li{
  list-style-type: none;
  float:left;
  width: 20px;
  color: #FFF;
  text-align: center;
}
ul li:nth-child(even){
  background-color: #222;
}
ul li:nth-child(odd){
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>display all</button>

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Один из вариантов - иметь массив функций, которые shift редактируются и вызываются на каждом интервале. При нажатии очистите интервал и forEach от остальных функций, все еще находящихся в массиве, и вызовите их:

var duration = 500;
const fns = [];
for(let i=0; i < 20; i++ ){
  const fn = () => $('ul').append('<li>'+ (i+1) +'</li>');
  fns.push(fn);
}
const interval = setInterval(() => {
  const fn = fns.shift();
  if (fn) fn();
  else clearTimeout(interval);
}, duration);

$('button').click(function(){
  fns.forEach(fn => fn());
  clearTimeout(interval)
});
ul li{
  list-style-type: none;
  float:left;
  width: 20px;
  color: #FFF;
  text-align: center;
}
ul li:nth-child(even){
  background-color: #222;
}
ul li:nth-child(odd){
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>display all</button>
0 голосов
/ 31 августа 2018

Вместо этого вы можете заменить цикл функцией, остальные работают нормально:

var duration = 500;

function range(i, n) {
  setTimeout(function() {
    $('ul').append('<li>' + (i) + '</li>')
    if (i < n) {
      range(i + 1, n);
    }
  }, duration);
}
range(1, 20);

$('button').click(function() {
  duration = 0;
});
ul li {
  list-style-type: none;
  float: left;
  width: 20px;
  color: #FFF;
  text-align: center;
}

ul li:nth-child(even) {
  background-color: #222;
}

ul li:nth-child(odd) {
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>display all</button>
0 голосов
/ 31 августа 2018

Вы можете использовать немного другой подход к событию нажатия кнопки, опустошив и восстановив список <ul> в случае нажатия кнопки.

Что вам также нужно помнить, это то, что ваши тайм-ауты должны быть отменены при нажатии кнопки. Чтобы достичь этого, вы можете подумать о сохранении идентификатора каждого тайм-аута, чтобы каждый тайм-аут мог быть очищен при нажатии кнопки.

Следующий код является одним из подходов к этому, который минимизирует количество корректировок вашего текущего кода:

    var duration = 500;

    // Declare timeout array to store timeout ids
    var timeouts = [];

    for(let i=0; i < 20; i++ ){

      // Store each timeout id, so that you can cancel them if 
      // button clicked
      timeouts[i] = setTimeout(function(){
         $('ul').append('<li>'+ (i+1) +'</li>')
      }, i * duration);

    }
    
    $('button').click(function(){
        
        // If button clicked, empty ul and repopulate it
        $('ul').empty()
    
      for(var i = 0; i < timeouts.length; i++) {

        // Clear timeout at i
        clearTimeout(timeouts[i]) 

        // Add li element for i
        $('ul').append('<li>'+ (i+1) +'</li>') 
      }
    
    
       duration = 0;
    });
ul li{
  list-style-type: none;
  float:left;
  width: 20px;
  color: #FFF;
  text-align: center;
}
ul li:nth-child(even){
  background-color: #222;
}
ul li:nth-child(odd){
  background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul></ul>
<br>
<button>display all</button>
...