Браузерные события, часть 1 из 5. Основные сведения

21.04.2022

Теги: DOMFrontendHTMLJavaScriptWeb-разработкаСобытиеТеория

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

Использование атрибута html

Обработчик может быть назначен прямо в html-разметке

<input type="button" onclick="alert('Клик!')" value="Нажми меня">

Атрибут html-тега — не самое удобное место для написания большого количества кода, поэтому лучше создать отдельную JavaScript-функцию и вызвать её там.

<script>
    function countClicks() {
        for (let i=1; i<=3; i++) {
            alert('Клик номер ' + i);
        }
    }
</script>

<input type="button" onclick="countClicks()" value="Считать клики!">

Использование свойства DOM-объекта

Можно назначать обработчик, используя свойство DOM-элемента

<input id="elem" type="button" value="Нажми меня!">
<script>
    elem.onclick = function() {
        alert('Спасибо');
    };
</script>

Убрать обработчик можно назначением elem.onclick = null.

Доступ к элементу через this

Внутри обработчика события this ссылается на текущий элемент, то есть на тот, на котором «висит» обработчик.

<button onclick="alert(this.innerHTML)">Нажми меня</button>

addEventListener

Фундаментальный недостаток описанных выше способов назначения обработчика — невозможность повесить несколько обработчиков на одно событие.

input.onclick = function() { alert(1); } // назначаем обработчик события
// .....
input.onclick = function() { alert(2); } // заменяем предыдущий обработчик

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

element.addEventListener(event, handler[, options]);

Здесь event — имя события, handler — ссылка на функцию-обработчик, а options — дополнительный объект со свойствами:

  • once — если true, тогда обработчик будет автоматически удалён после выполнения.
  • capture — фаза срабатывания обработчика (всплытие или погружение). Может быть false/true или {capture: false/true}.
  • passive — значение true указывает, что обработчик никогда не вызовет preventDefault().

Для удаления обработчика следует использовать removeEventListener

element.removeEventListener(event, handler[, options]);

Метод addEventListener позволяет добавлять несколько обработчиков на одно событие одного элемента

<input id="elem" type="button" value="Нажми меня"/>

<script>
    function handlerOne() {
        alert('Первый обработчик');
    };

    function handlerTwo() {
        alert('Второй обработчик');
    }

    elem.addEventListener('click', handlerOne); // Первый обработчик
    elem.addEventListener('click', handlerTwo); // Второй обработчик
</script>

Объект события

Чтобы хорошо обработать событие, могут понадобиться детали того, что произошло. Не просто «клик мышкой» или «нажатие клавиши», а также — какие координаты указателя мыши, какая клавиша нажата и так далее. Когда происходит событие, браузер создаёт объект события, записывает в него детали и передаёт его в качестве аргумента функции-обработчику.

<input id="elem" type="button" value="Нажми меня">

<script>
    elem.onclick = function(event) {
        // вывести тип события, элемент и координаты клика
        alert(event.type + ' на ' + event.currentTarget);
        alert('Координаты: ' + event.clientX + ':' + event.clientY);
    };
</script>

Здесь event.type — тип события, event.target — самый глубокий элемент, на котором произошло событие, event.currentTarget — элемент, на котором сработал обработчик.

Объект-обработчик handleEvent

Мы можем назначить обработчиком не только функцию, но и объект при помощи addEventListener. В этом случае, когда происходит событие, вызывается метод объекта handleEvent.

<button id="elem">Нажми меня</button>

<script>
    elem.addEventListener('click', {
        handleEvent(event) {
            alert(event.type + ' на ' + event.currentTarget);
        }
    });
</script>

Мы также можем использовать класс для этого

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Событие</title>
    <script>
        class Menu {
            handleEvent(event) {
                switch(event.type) {
                    case 'mousedown':
                        elem.innerHTML += ' Нажата кнопка мыши';
                        break;
                    case 'mouseup':
                        elem.innerHTML += ' Отжата кнопка мыши';
                        break;
                }
            }
        }
    </script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let menu = new Menu();
            elem.addEventListener('mousedown', menu);
            elem.addEventListener('mouseup', menu);
        });
    </script>
</head>
<body>
    <button id="elem">Нажми меня</button>
</body>
</html>

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

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Событие</title>
    <script>
        class Menu {
            handleEvent(event) {
                this[event.type](event);
            }

            mousedown(event) {
                elem.innerHTML += ' Кнопка мыши нажата';
            }

            mouseup(event) {
                elem.innerHTML += ' Кнопка мыши отжата';
            }
        }
    </script>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let menu = new Menu();
            elem.addEventListener('mousedown', menu);
            elem.addEventListener('mouseup', menu);
        });
    </script>
</head>
<body>
    <button id="elem">Нажми меня</button>
</body>
</html>

Поиск: Frontend • HTML • JavaScript • Web-разработка • Событие • Теория • Event • DOM

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.