Javascript - Приостановка setInterval()
Как приостановить и возобновить функцию setInterval() с помощью Javascript?
Например, возможно, у меня есть секундомер, чтобы рассказать вам количество секунд, которые вы просматривали на веб-странице. Появляются кнопки "Пауза" и "Возобновить". Причина, по которой clearInterval() не будет работать здесь, заключается в том, что если пользователь нажимает кнопку "Пауза" на 40-й и 800-й миллисекундах, когда он нажимает кнопку "Возобновить", количество прошедших секунд должно увеличиваться на 1 после 200 миллисекунд. Если я использую функцию clearInterval() в переменной таймера (при нажатии кнопки паузы), а затем снова используя функцию setInterval() в переменной таймера (когда нажата кнопка возобновления), количество прошедших секунд будет увеличиваться на 1 только после 1000 миллисекунд, что разрушает точность секундомера.
Итак, как мне это сделать?
Ответы
Ответ 1
Вы можете использовать флаг для отслеживания состояния:
var output = $('h1');
var isPaused = false;
var time = 0;
var t = window.setInterval(function() {
if(!isPaused) {
time++;
output.text("Seconds: " + time);
}
}, 1000);
//with jquery
$('.pause').on('click', function(e) {
e.preventDefault();
isPaused = true;
});
$('.play').on('click', function(e) {
e.preventDefault();
isPaused = false;
});
h1 {
font-family: Helvetica, Verdana, sans-serif;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Seconds: 0</h1>
<button class="play">Play</button>
<button class="pause">Pause</button>
Ответ 2
Вы не должны измерять время в функции интервала. Вместо этого просто сэкономьте время, когда таймер был запущен, и измерьте разницу, когда таймер был остановлен/приостановлен. Используйте setInterval только для обновления отображаемого значения. Таким образом, нет необходимости останавливать таймер, и таким образом вы получите максимально возможную точность.
Ответ 3
Почему бы не использовать более простой подход? Добавьте класс!
Просто добавьте класс, который сообщает интервалу ничего не делать. Например: при наведении.
var i = 0;
this.setInterval(function() {
if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
console.log('Counting...');
$('#counter').html(i++); //just for explaining and showing
} else {
console.log('Stopped counting');
}
}, 500);
/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
$(this).addClass('pauseInterval');
},function() { //mouse leave
$(this).removeClass('pauseInterval');
}
);
/* Other example */
$('#pauseInterval').click(function() {
$('#counter').toggleClass('pauseInterval');
});
body {
background-color: #eee;
font-family: Calibri, Arial, sans-serif;
}
#counter {
width: 50%;
background: #ddd;
border: 2px solid #009afd;
border-radius: 5px;
padding: 5px;
text-align: center;
transition: .3s;
margin: 0 auto;
}
#counter.pauseInterval {
border-color: red;
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="counter"> </p>
<button id="pauseInterval">Pause</button></p>
Ответ 4
Хотя @Jonas Giuro прав, говоря, что:
Вы не можете использовать PAUSE для функции setInterval, вы можете остановить ее (clearInterval) или запустить ее
С другой стороны, это поведение можно моделировать с помощью подхода @VitaliyG:
Вы не должны измерять время в функции интервала. Вместо этого просто сэкономьте время, когда таймер был запущен, и измерьте разницу, когда таймер был остановлен/приостановлен. Используйте setInterval только для обновления отображаемого значения.
var output = $('h1');
var isPaused = false;
var time = new Date();
var offset = 0;
var t = window.setInterval(function() {
if(!isPaused) {
var milisec = offset + (new Date()).getTime() - time.getTime();
output.text(parseInt(milisec / 1000) + "s " + (milisec % 1000));
}
}, 10);
//with jquery
$('.toggle').on('click', function(e) {
e.preventDefault();
isPaused = !isPaused;
if (isPaused) {
offset += (new Date()).getTime() - time.getTime();
} else {
time = new Date();
}
});
h1 {
font-family: Helvetica, Verdana, sans-serif;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Seconds: 0</h1>
<button class="toggle">Toggle</button>