img

Обработчики событий JavaScript – как обрабатывать события в JS

 

Что такое события?

События – это действия, происходящие в момент взаимодействия пользователя со страницей, например, нажатие на элемент, ввод текста в поле или загрузка страницы.

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

Что значит «обработать событие»?

Чтобы было проще, давайте предположим, что вы хотите посетить мероприятие по веб-разработке в вашем городе.

Для этого вы регистрируетесь на эту встречу под названием «Women Who Code» и подписываетесь на уведомления. В таком случае, когда бы ни была запланирована новая встреча, вы получите оповещение. Это и есть обработка событий!

Здесь «событие» - это новая встреча. При публикации новой встречи, веб-сайт meetup.com улавливает это изменение, и, как следствие, «обрабатывает» это событие. После чего он оповещает вас, тем самым совершая «действие», связанное с этим событием.

В браузере события обрабатываются точно так же. Браузер обнаруживает изменение и оповещает функцию (обработчик событий), которая прослушивает определенный тип события. Далее функция выполняет необходимые действия. 

Давайте посмотрим на пример обработчика события click

<div class="buttons">
  <button>Press 1</button>
  <button>Press 2</button>
  <button>Press 3</button>
</div>
const buttonContainer = document.querySelector('.buttons');
console.log('buttonContainer', buttonContainer);

buttonContainer.addEventListener('click', event => {
  console.log(event.target.value)
})

Какие есть типы событий?

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

Далее перечислены самые распространенные события: 

onclick dblclick mousedown mouseup mousemove keydown keyup touchmove touchstart touchend onload onfocus onblur onerror onscroll

Различные фазы событий – фаза погружения, фаза цели и фаза всплытия

Когда событие перемещается по модели DOM, а именно всплывает наверх или просачивается вниз, это называется распространением события. Событие распространяется по DOM-дереву. 

События происходят в две фазы: фаза всплытия (bubbling phase) и фаза погружения (capturing phase).

В фазе погружения, которую также называют фазой просачивания, событие «просачивается» к элементу, который вызвал событие. 

Оно начинает с элемента корневого уровня и обработчика, а далее распространяется вниз к элементу. Фаза погружения завершается тогда, когда событие достигает цели - target.

В фазе всплытия событие «всплывает» по DOM-дереву. Сначала оно погружается и обрабатывается самым дальним обработчиком (тем, который находится ближе всего к элементу, на котором произошло событие). После чего оно всплывает (или распространяется) на более высокие уровни DOM-дерева, все выше к своим родительским узлам, а затем и к его корню.

Вот подсказка, которая поможет вам запомнить это: 

trickle down, bubble up

А ниже представлена инфографика с quirkmode, которая поможет вам лучше разобраться:

               / \

---------------| |-----------------

| элемент1     | |                |

|   -----------| |-----------     |

|   |элемент2  | |          |     |

|   -------------------------     |

|        Событие ВСПЛЫВАЕТ        |

-----------------------------------

 

               | |

---------------| |-----------------

| элемент1     | |                |

|   -----------| |-----------     |

|   |элемент2  \ /          |     |

|   -------------------------     |

|       Событие ПОГРУЖАЕТСЯ       |

-----------------------------------

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

Вы можете зарегистрировать обработчики событий для любой из фаз с помощью функции addEventListener(type, listener, useCapture). Если параметр useCapture задается как false, то считаем, что событие находится в фазе всплытия. Иначе – в фазе погружения. 

Порядок фаз зависит от браузера 

Для того, чтобы проверить, какой браузер первым принимает погружение, попробуйте выполнить следующий код в JSFiddle:

<div id="child-one">
    <h1>
      Child One
    </h1>
  </div>

const childOne = document.getElementById("child-one");

const childOneHandler = () => {
console.log('Captured on child one')
}

const childOneHandlerCatch = () => {
console.log('Captured on child one in capture phase')
}

childOne.addEventListener("click", childOneHandler); 
childOne.addEventListener("click", childOneHandlerCatch, true); 

В Firefox, Safari и Chrome результат будет такой:

(Первыми срабатывают события в фазе погружения)

Как прослушивать события?

Есть два способа прослушивания событий:

  1. addEventListener
  2. встраиваемые события, такие как onclick
//addEventListener
document.getElementByTag('a').addEventListener('click', onClickHandler);

//inline using onclick
<a href="#" onclick="onClickHandler">Click me</a>

Что лучше – встраиваемое событие или addEventListener?

  1. С помощью addEventListener можно регистрировать неограниченное количество обработчиков событий.
  2. Также можно использовать removeEventListener для удаления обработчиков событий.
  3. Флаг useCapture можно использовать для указания, в какой фазе должно обрабатываться событие – в фазе погружения или в фазе всплытия.

Примеры программного кода в реальном действии

Вы можете попробовать запустить эти события в JSFiddle, чтобы поэкспериментировать с ними.

<div id="wrapper-div">
  <div id="child-one">
    <h1>
      Child One
    </h1>
  </div>
  <div id="child-two" onclick="childTwoHandler">
    <h1>
      Child Two
    </h1>
  </div>

</div>

const wrapperDiv = document.getElementById("wrapper-div");
const childOne = document.getElementById("child-one");
const childTwo = document.getElementById("child-two");

const childOneHandler = () => {
console.log('Captured on child one')
}

const childTwoHandler = () => {
console.log('Captured on child two')
}

const wrapperDivHandler = () => {
console.log('Captured on wrapper div')
}

const childOneHandlerCatch = () => {
console.log('Captured on child one in capture phase')
}

const childTwoHandlerCatch = () => {
console.log('Captured on child two in capture phase')
}

const wrapperDivHandlerCatch = () => {
console.log('Captured on wrapper div in capture phase')
}


childOne.addEventListener("click", childOneHandler); 
childTwo.addEventListener("click", childTwoHandler); 
wrapperDiv.addEventListener("click", wrapperDivHandler); 

childOne.addEventListener("click", childOneHandlerCatch, true); 
childTwo.addEventListener("click", childTwoHandlerCatch, true); 
wrapperDiv.addEventListener("click", wrapperDivHandlerCatch, true); 

Резюмируя

Фазы событий – это погружение (DOM -> target), всплытие (target -> DOM) и цель (target).

Cобытия можно прослушивать с помощью addEventListener  или встраиваемых событий, таких как onclick.

С addEventListener можно добавлять несколько событий, а с onclick нельзя. 

onclick можно добавить в качестве атрибута HTML, а addEventListener можно добавить только внутри элементов <script>.

addEventListener может принимать третий аргумент, который может остановить распространение события. 

 

Ссылка
скопирована
Программирование
Скидка 25%
Фронтенд-разработчик с нуля
Погрузитесь в мир веб-разработки, освоив основные инструменты работы: HTML, CSS, JavaScript. Научитесь работать с дизайн-макетами и адаптивной версткой, сверстаете свои первые страницы и поймете, как строить карьерный трек в ИТ.
Получи бесплатный
вводный урок!
Пожалуйста, укажите корректный e-mail
отправили вводный урок на твой e-mail!
Получи все материалы в telegram и ускорь обучение!
img
Еще по теме:
img
За последние годы микрослужбы прошли путь от обычного переоцененного модного словечка до вещи, которую вы, как специалист по про
img
Введение Резидентные базы данных (или хранилища в памяти) по большей части делают упор на хранилище данных в памяти, а не на жес
img
  Многие люди рассуждают так: «зачем, ну зачем мне изучать еще один язык программирования?» Для них это лишнее, и они стараютс
img
Введение Объекты в Kubernetes – это базовые постоянные сущности, которые описывают состояние кластера Kubernetes. Модули – это э
img
  Довольно часто мы встречаемся с компонентами архитектуры программного обеспечения, которые являются частью любой системы, но п
img
  Ключевые отличия между JDK, JRE и JVM: JDK – это набор средств для разработки программного обеспечения, JRE – это програ
Комментарии
ЛЕТНИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59