Выбрать главу

Похожий набор функций, 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, чтобы гарантировать, что вы делаете это не слишком часто. Это обычно называют «устранением помех» в событии. К этому существует несколько слегка различающихся подходов.

В первом примере надо сделать что-то, когда пользователь печатает, но не надо делать это сразу после запуска каждого события нажатия на клавиши. Когда они быстро печатают, нам надо подождать, когда возникнет пауза. Вместо немедленного выполнения действия в обработчике, мы устанавливаем таймаут. Также мы очищаем предыдущий таймаут, если он был, так что если события близко одно от другого (ближе, чем задержка таймера), предыдущее событие будет отменено.

<textarea>Напишите тут что-нибудь...</textarea>

<script>

  var textarea = document.querySelector("textarea");

  var timeout;

  textarea.addEventListener("keydown", function() {

    clearTimeout(timeout);

    timeout = setTimeout(function() {

      console.log("Вы остановились.");

    }, 500);

  });

</script>

Если задать undefined для clearTimeout, или вызвать его с таймаутом, который уже произошёл, то ничего не произойдёт. Таким образом, не надо осторожничать при его вызове, и мы просто поступаем так для каждого события.

Можно использовать немного другой подход, если нам надо разделить ответы минимальными промежутками времени, но при этом запускать их в то время, когда происходят события, а не после. К примеру, надо реагировать на события "mousemove", показывая текущие координаты мыши, но только каждые 250 миллисекунд.

<script>

  function displayCoords(event) {

    document.body.textContent =

      "Мышь на " + event.pageX + ", " + event.pageY;

  }

  var scheduled = false, lastEvent;

  addEventListener("mousemove", function(event) {

    lastEvent = event;

    if (!scheduled) {

      scheduled = true;

      setTimeout(function() {

        scheduled = false;

        displayCoords(lastEvent);

      }, 250);

    }

  });

</script>

Итог

Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не властны. Для их регистрации используется метод addEventListener.

У событий есть определяющий их тип ("keydown", "focus", и так далее). Большинство событий вызываются конкретными узлами DOM, и затем распространяются на их предков, позволяя связанными с ними обработчикам обрабатывать их.

При вызове обработчика ему передаётся объект события с дополнительной информацией о событии. У объекта также есть методы, позволяющие остановить дальнейшее распространение (stopPropagation) и предотвратить обработку события браузером по умолчанию (preventDefault).

Нажатия на клавиши запускают события "keydown", "keypress" и "keyup". Нажатия на кнопки мыши запускают события "mousedown", "mouseup" и "click". Движения мыши запускают события "mousemove" и, возможно, "mouseenter" или "mouseout".

Прокрутку можно обнаружить через событие "scroll", а изменения фокуса через события "focus" и "blur". Когда заканчивается загрузка документа, у объекта window запускается событие "load".

В одно и то же время может работать один участок программы. Поэтому обработчики событий и другие запланированные скрипты будут ждать окончания работы текущих.

Упражнения

Цензура клавиатуры

В промежутке с 1928 по 2013 год турецкие законы запрещали использование букв Q, W и X в официальных документах. Это являлось частью общей инициативы подавления курдской культуры – эти буквы используются в языке курдов, но не у турков.