JavaRush /Курсы /Модуль 1: Web Core /Способы навешивания обработчиков событий

Способы навешивания обработчиков событий

Модуль 1: Web Core
23 уровень , 1 лекция
Открыта

1. Способ 1: Навешивание обработчика прямо в HTML

В JavaScript обработчик события (event handler) — это функция, которая запускается, когда с элементом происходит определённое событие: щёлкнули мышкой, навели курсор, что-то ввели и так далее.

Пример: кнопка «Показать котика» должна по клику показывать картинку котика. Для этого мы «навешиваем» обработчик события на кнопку.

Но как это сделать? Есть три основных способа, и у каждого свои плюсы, минусы и подводные камни.

Это самый древний и, пожалуй, самый «олдскульный» способ. Вы прямо в HTML-элементе пишете специальный атрибут, начинающийся с on, например: onclick, onmouseover, onchange и т.д.

Пример:

<button onclick="alert('Мяу! Я котик!')">Показать котика</button>

Когда пользователь кликнет на кнопку, выполнится код из атрибута onclick. В данном случае — всплывёт «мяукающее» сообщение.

Пример с вызовом функции

Лучше не писать весь код прямо в атрибуте, а вызывать функцию:

<button onclick="showCat()">Показать котика</button>

<script>
  function showCat() {
    alert('Мяу! Я котик!');
  }
</script>

Как это работает?

  • Браузер видит атрибут onclick и понимает: «О, надо слушать клики по этой кнопке и запускать showCat».
  • Всё просто, но есть нюансы.

Плюсы

  • Быстро, наглядно, понятно даже бабушке.
  • Работает даже в Internet Explorer 6 (ну мало ли, вдруг вы пишете сайт для музея древностей).

Минусы

  • Логика разбросана по HTML и JS. Если у вас много обработчиков — HTML превращается в «суп из событий».
  • Трудно переиспользовать код.
  • Плохо для масштабных проектов: сложно поддерживать, сложно тестировать.
  • Неудобно, если обработчик большой или зависит от переменных JS.

Итог

Используйте только для простых демо, или когда ну очень лень. В реальных проектах лучше не надо.

2. Способ 2: Навешивание обработчика через свойство DOM-элемента

Второй способ — назначить обработчик как свойство объекта DOM-элемента. Каждый элемент в DOM имеет свойства вида onclick, onchange, oninput и т.д.

Пример

<button id="btn">Показать котика</button>

<script>
  // Находим кнопку по id
  const button = document.getElementById('btn');

  // Навешиваем обработчик через свойство
  button.onclick = function() {
    alert('Мяу! Я котик!');
  };
</script>

Как это работает?

  • JS-код находит элемент (например, по id).
  • Через свойство onclick присваивает функцию — обработчик.
  • Теперь при клике на кнопку функция вызовется.

Плюсы

  • Весь JS-код — в JS, а не размазан по HTML.
  • Проще поддерживать и тестировать.
  • Можно менять обработчик динамически (например, в зависимости от условий).

Минусы

  • На один тип события можно назначить только ОДИН обработчик через свойство. Если вы дважды напишете button.onclick = ..., второй обработчик перезапишет первый.
button.onclick = function() { alert('Первый!'); };
button.onclick = function() { alert('Второй!'); };
// При клике сработает только "Второй!"
  • Нет гибкого управления (например, нельзя легко добавить несколько обработчиков одного события).
  • Нельзя повесить обработчик на событие, если имя события не поддерживается как свойство (редко, но бывает).

Итог

Хорошо для простых случаев и небольших проектов. Часто встречается в учебных примерах. Для более сложных сценариев — есть способ №3.

3. Способ 3: addEventListener — современно, гибко, удобно

Самый мощный и рекомендуемый способ — использовать метод addEventListener.

Синтаксис

element.addEventListener('тип_события', обработчик, [опции]);
  • тип_события — строка, например, 'click', 'input', 'keydown'.
  • обработчик — функция (или ссылка на функцию).
  • [опции] — дополнительные настройки (чаще всего не нужны для простых случаев).

Пример

<button id="btn">Показать котика</button>

<script>
  const button = document.getElementById('btn');

  button.addEventListener('click', function() {
    alert('Мяу! Я котик!');
  });
</script>

Преимущества

  • Можно навесить СКОЛЬКО УГОДНО обработчиков одного события на один элемент. Все они отработают по очереди.
  • Можно легко удалить обработчик (об этом — в следующей лекции).
  • Можно навешивать обработчики на любые события, даже пользовательские.
  • Можно управлять фазой события (всплытие/перехват), но это уже для продвинутых Jedi.

Пример с несколькими обработчиками

button.addEventListener('click', function() {
  alert('Первый обработчик!');
});

button.addEventListener('click', function() {
  alert('Второй обработчик!');
});

Теперь при клике вы увидите оба сообщения — по очереди.

Пример с отдельной функцией

function showCat() {
  alert('Мяу! Я котик!');
}
button.addEventListener('click', showCat);

Особенности

  • Имя события пишется без on! То есть 'click', а не 'onclick'.
  • Можно навесить обработчик не только на элементы, но и на window, document и даже на пользовательские объекты (если они поддерживают события).

4. Сравнение способов — таблица

Способ Код в HTML Код в JS Несколько обработчиков Гибкость Где применять
Через атрибут on... Да Нет Нет Низкая Демо, очень простые примеры
Через свойство on... Нет Да Нет Средняя Простые проекты, учебные
addEventListener Нет Да Да Высокая Современные сайты и SPA

5. Практика: делаем интерактивную страницу

Давайте напишем небольшой «живой» пример. Пусть у нас есть кнопка, при клике на которую появляется картинка котика.

HTML:

<button id="showBtn">Показать котика</button>
<div id="catBox"></div>

JS — способ 1 (через HTML):

<button onclick="showCat()">Показать котика</button>
<div id="catBox"></div>
<script>
  function showCat() {
    document.getElementById('catBox').innerHTML = '<img src="https://placekitten.com/200/200">';
  }
</script>

JS — способ 2 (через свойство):

const btn = document.getElementById('showBtn');
btn.onclick = function() {
  document.getElementById('catBox').innerHTML = '<img src="https://placekitten.com/200/200">';
};

JS — способ 3 (addEventListener):

const btn = document.getElementById('showBtn');
btn.addEventListener('click', function() {
  document.getElementById('catBox').innerHTML = '<img src="https://placekitten.com/200/200">';
});

Поиграйте с каждым способом! Заменяйте обработчики, добавляйте ещё кнопки, пробуйте навесить два обработчика на одну кнопку через addEventListener.

6. Особенности и нюансы

Передача параметров в обработчик

Иногда хочется передать аргумент в обработчик. Например, вывести имя котика.

Через HTML:

<button onclick="showCat('Барсик')">Показать котика</button>
<script>
  function showCat(name) {
    alert('Котик по имени ' + name);
  }
</script>

Через addEventListener:

btn.addEventListener('click', function() {
  showCat('Барсик');
});

Или с помощью стрелочной функции:

btn.addEventListener('click', () => showCat('Барсик'));

this в обработчике

В обработчиках, навешанных через HTML-атрибут или свойство, this внутри функции указывает на элемент, на который навешан обработчик.

btn.onclick = function() {
  this.textContent = 'Я был нажат!';
};

В обработчиках, навешанных через addEventListener, this ведёт себя так же (если не используете стрелочную функцию!). Стрелочные функции не имеют собственного this, поэтому внутри них this будет из внешнего контекста.

7. Типичные ошибки при навешивании обработчиков

Ошибка №1: Путаница между on... и addEventListener.
Очень часто новички пишут так:

btn.addEventListener('onclick', ...); // НЕПРАВИЛЬНО

Имя события должно быть без on: 'click', а не 'onclick'.

Ошибка №2: Перезапись обработчиков через свойство.
Если вы дважды напишете:

btn.onclick = foo;
btn.onclick = bar;

Второй обработчик полностью заменит первый, а не добавится к нему.

Ошибка №3: Передача функции с ()
Если написать:

btn.onclick = showCat();

Это вызовет функцию сразу при выполнении скрипта, а не при клике! Нужно писать или ссылку на функцию, или анонимную функцию:

btn.onclick = showCat; // правильно
btn.onclick = function() { showCat(); }; // тоже правильно

Ошибка №4: Не найден элемент
Если вы пытаетесь навесить обработчик на элемент, которого ещё нет в DOM (например, скрипт стоит в <head>), получите ошибку. Решение: ставьте скрипт внизу страницы или используйте событие DOMContentLoaded.

Ошибка №5: Использование стрелочных функций, если нужен this
Стрелочные функции не имеют своего this, поэтому если вам нужен доступ к элементу через this, используйте обычную функцию.

1
Задача
Модуль 1: Web Core, 23 уровень, 1 лекция
Недоступна
Генератор чисел
Генератор чисел
1
Задача
Модуль 1: Web Core, 23 уровень, 1 лекция
Недоступна
Динамический генератор
Динамический генератор
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ