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

Как видно из примера, эта функция получает в точности такие же типы аргументов, что и функция addEventListener. Причина тому проста. Когда мы прослушиваем событие в элементе или объекте, JavaScript использует eventName, eventHandler и значение true / false, чтобы опознать слушателя событий. Чтобы удалить этого слушателя событий, нам нужно указать в точности такие же аргументы. Вот пример:

document.addEventListener("click", changeColor, false);

document.removeEventListener("click", changeColor, false);

function changeColor() {

document.body.style.backgroundColor = "#FFC926";

}

Слушатель событий, которого мы добавили в первой строке, полностью нейтрализован вызовом removeEventListener в выделенной второй строке. Если вызов removeEventListener использует аргументы, отличные от указанных в соответствующем вызове addEventListener, то его усилия будут проигнорированы и прослушивание продолжится.

КОРОТКО О ГЛАВНОМ

Что ж, это все, что нужно для ознакомления с событиями. Помните: у вас есть функция addEventListener, которая позволяет зарегистрировать функцию обработчика событий. Эта функция обработчика событий будет вызываться при запуске события, которое примет прослушиватель событий. Хотя мы коснулись некоторых других тем, они станут более понятными, если рассмотреть их в контексте более сложных примеров, связанных с событиями.

Глава 32. Всплытие и погружение событий

В предыдущей главе вы узнали, как использовать функцию addEventListener для прослушивания событий, на которые нужно среагировать. Но кроме основ мы также затронули важную тему того, как именно события срабатывают. Событие — это не обособленное возмущение. Подобно бабочке, машущей крыльями, землетрясению, падению метеорита или визиту Годзиллы, многие события расходятся волнами и воздействуют на другие элементы, которые лежат у них на пути.

Сейчас я превращусь в Шерлока Холмса и раскрою вам тайну, что же именно происходит при срабатывании события. Вы узнаете о двух фазах, в которых пребывают события, поймете, почему это важно знать, а также познакомитесь с некоторыми трюками, которые помогут лучше контролировать события.

Событие опускается. Событие поднимается

Для наглядности оформим все в виде простого примера:

<!DOCTYPE html>

<html>

<head>

<title>Events!</title>

</head>

<body id="theBody" class="item">

<div id="one_a" class="item">

<div id="two" class="item">

<div id="three_a" class="item">

<button id="buttonOne" class="item">one</button>

</div>

<div id="three_b" class="item">

<button id="buttonTwo" class="item">two</button>

<button id="buttonThree" class="item">three</button>

</div>

</div>

</div>

<div id="one_b" class="item">

</div>

<script>

</script>

</body>

</html>

Вроде бы ничего особенного здесь не происходит. HTML должен выглядеть достаточно понятно, и его представление DOM приведено на рис. 32.1.

Отсюда и начнем наше расследование. Давайте представим, что щелкаем по элементу buttonOne. Исходя из пройденного материала, вы знаете, что при этом запустится событие клика. Интересная же часть, которую до этого я опускал, заключается в том, откуда конкретно будет запущено это событие. Оно (как почти каждое событие в JavaScript) не возникает в элементе, с которым произошло взаимодействие. Иначе все бы было слишком просто и логично.

Рис. 32.1. Так выглядит DOM для разметки, приведенной выше

Вместо этого событие стартует из корня вашего документа:

Начиная с корня, событие проделывает путь по узким тропкам DOM и останавливается у элемента, который его вызвал, а именно buttonOne (также известного как целевое событие):

Как показано на рисунке, событие совершает прямой путь, но при этом наглым образом уведомляет каждый элемент на своем пути. Это означает, что если бы вы прослушивали событие клика в body, one_a, two или three_a, то сработал бы связанный с ними обработчик событий. Это важная деталь, к которой мы еще вернемся.

Как только наше событие достигнет своей цели, оно не остановится и, как кролик из известной рекламы батареек, продолжает движение по своим следам обратно к корню:

Как и прежде, каждый элемент на пути события будет уведомлен о его присутствии.

Знакомьтесь с фазами

Важно заметить, что не имеет значения, где в DOM инициируется событие. Оно всегда начинает движение от корня, спускается вниз до встречи с целью, а затем возвращается к корню. Этот путь имеет официальное определение, поэтому давайте рассмотрим его с этой позиции.