// generate a random color - random hex value
const randomColor = function () {
const hex = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += hex[Math.floor(Math.random() * 16)];
}
return color;
};
let intervalId;
const startChangingColor = function () {
intervalId = setInterval(changeBg, 3000);
function changeBg() {
document.body.style.backgroundColor = randomColor();
}
};
const stopChangingColor = function () {
clearInterval(intervalId);
};
document.querySelector('#start').addEventListener('click', startChangingColor);
document.querySelector('#stop').addEventListener('click', stopChangingColor);
В этом коде есть две кнопки: одна для запуска, другая для остановки. Когда я нажимаю кнопку «Пуск», цвет начинает меняться. Однако когда я нажимаю кнопку «Стоп», она не работает; это должно остановить изменение цвета.
Ваша функция запуска должна проверять, запущен ли уже таймер (проверяя, не является ли идентификатор undefined
), и в этом случае ничего не делать. И ваша функция остановки должна затем установить идентификатор таймера на undefined
. Это позволит предотвратить несколько последовательных нажатий кнопки запуска, запускающих несколько таймеров, из которых вы можете остановить только последний.
Ваш код кажется правильным. Пожалуйста, дважды проверьте идентификаторы ваших HTML-кнопок.
проблема в том, что когда вы нажимаете кнопку «Пуск», код не проверяет, есть ли уже эффект изменения цвета фона. Если вы нажмете кнопку «Пуск» несколько раз, будет создан эффект многократного изменения цвета фона. Пока вы нажимаете «стоп», останавливается ТОЛЬКО последний.
и в функции интервала остановки вам необходимо сбросить идентификатор на undefined
, его можно перезапустить снова, нажав кнопку «Пуск».
так:
// generate a random color - random hex value
const randomColor = function() {
const hex = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += hex[Math.floor(Math.random() * 16)];
}
return color;
};
let intervalId;
const startChangingColor = function() {
// need check if already has background change effect
if (intervalId !== undefined) {
return;
}
intervalId = setInterval(changeBg, 3000);
function changeBg() {
document.body.style.backgroundColor = randomColor();
}
};
const stopChangingColor = function() {
clearInterval(intervalId);
// reset the id to undefined
intervalId = undefined;
};
document.querySelector('#start').addEventListener('click', startChangingColor);
document.querySelector('#stop').addEventListener('click', stopChangingColor);
<div>
<button id = "start">start</button>
<button id = "stop">stop</button>
</div>
Вы также можете просто вызвать clearInterval( intervalId )
перед вызовом setInterval
, поскольку все, что не является идентификатором internval, в любом случае игнорируется. Таким образом, вы никогда не сможете запустить два таймера и вам не понадобятся дополнительные проверки.
Из-за того, как работают setInterval
и clearInterval
, вам лучше просто вызвать stop
непосредственно перед тем, как начать очищать любые интервалы активации:
const randomColor = function () {
const hex = '0123456789ABCDEF';
let color = '#';
for (let i = 0; i < 6; i++) {
color += hex[Math.floor(Math.random() * 16)];
}
return color;
};
let intervalId;
const startChangingColor = function () {
stopChangingColor();
intervalId = setInterval(changeBg, 3000);
function changeBg() {
document.body.style.backgroundColor = randomColor();
}
};
const stopChangingColor = function () {
clearInterval(intervalId);
};
document.querySelector('#start').addEventListener('click', startChangingColor);
document.querySelector('#stop').addEventListener('click', stopChangingColor);
<button id = "start">Start</button>
<button id = "stop">Stop</button>
clearInterval
, как вы видите в документации здесь, неважно, что вы передаете:
Если предоставленный параметр не идентифицирует ранее установленное действие, этот метод ничего не делает.
Если это действительный идентификатор интервала, он отменит его, если это что-то еще, он будет проигнорирован, поэтому нет необходимости проверять, существует ли он или что-то в этом роде, просто очистите его с помощью переменной, которая содержит/будет хранить ваш идентификатор.
Как описано в большинстве приведенных выше ответов, одной из причин может быть то, что вы создаете несколько интервалов, последовательно нажимая кнопку «Пуск», а затем нажимая кнопку «Стоп», что фактически уничтожает только последний созданный интервал.
Я также предполагаю, что фрагмент выше, которым вы поделились, используется в каком-то библиотечном компоненте (например, компоненте React), который выполняет повторную визуализацию и теряет значение интервала при последующих повторных визуализациях. Если это так, попробуйте сохранить интервалId в состоянии.
Можете ли вы создать фрагмент стека, повторяющий вашу проблему? В настоящее время ваш код не вызывает описанную вами проблему. Возможно, вы дважды нажимаете «Пуск», прежде чем нажать «Стоп»?