>
> document.body.style.background = "blue";
> setTimeout(function() {
> document.body.style.background = "yellow";
> }, 2000);
>
Иногда вам надо отменить запланированную функцию. Это можно сделать, сохранив значение, возвращаемое >setTimeout
, и затем вызвав с ним >clearTimeout
.
>var bombTimer = setTimeout(function() {
> console.log("BOOM!");
>}, 500);
>if (Math.random() < 0.5) { // 50% chance
> console.log("Defused.");
> clearTimeout(bombTimer);
>}
Функция >cancelAnimationFrame
работает так же, как >clearTimeout
– вызов её со значением, возвращённым >requestAnimationFrame
, отменит этот кадр (если он уже не был вызван).
Похожий набор функций, >setInterval
и >clearInterval
используется для установки таймеров, которые будут повторяться каждые X миллисекунд.
>var ticks = 0;
>var clock = setInterval(function() {
> console.log("tick", ticks++);
> if (ticks == 10) {
> clearInterval(clock);
> console.log("stop.");
> }
>}, 200);
Устранение помех (debouncing)
У некоторых событий есть возможность выполняться быстро и много раз подряд (например, >"mousemove"
и >"scroll"
). При обработке таких событий надо быть осторожным и не делать ничего «тяжёлого», или ваш обработчик займёт столько времени на выполнение, что взаимодействие с документом будет медленным и прерывистым.
Если в таком обработчике надо сделать что-то нетривиальное, можно использовать >setTimeout
, чтобы гарантировать, что вы делаете это не слишком часто. Это обычно называют «устранением помех» в событии. К этому существует несколько слегка различающихся подходов.
В первом примере надо сделать что-то, когда пользователь печатает, но не надо делать это сразу после запуска каждого события нажатия на клавиши. Когда они быстро печатают, нам надо подождать, когда возникнет пауза. Вместо немедленного выполнения действия в обработчике, мы устанавливаем таймаут. Также мы очищаем предыдущий таймаут, если он был, так что если события близко одно от другого (ближе, чем задержка таймера), предыдущее событие будет отменено.
>
>
> var textarea = document.querySelector("textarea");
> var timeout;
> textarea.addEventListener("keydown", function() {
> clearTimeout(timeout);
> timeout = setTimeout(function() {
> console.log("Вы остановились.");
> }, 500);
> });
>
Если задать >undefined
для >clearTimeout
, или вызвать его с таймаутом, который уже произошёл, то ничего не произойдёт. Таким образом, не надо осторожничать при его вызове, и мы просто поступаем так для каждого события.
Можно использовать немного другой подход, если нам надо разделить ответы минимальными промежутками времени, но при этом запускать их в то время, когда происходят события, а не после. К примеру, надо реагировать на события