Браузерные события элементов Ч. 2
Первая часть: https://studyjavascript.blogspot.com/2019/03/1.html
Создание собственных событий
JavaScript позволяет генерировать события на элементах.
Рассмотрим код:
<button id="myButton">Нажми</button>
<div id="myDiv"></div>
В html-коде у нас кнопка и див
const myButton = document.querySelector("#myButton");
const myDiv = document.querySelector("#myDiv");
myButton.addEventListener("click", () => {
const event = new CustomEvent("click");
myDiv.dispatchEvent(event);
});
myDiv.addEventListener("click", () => {
console.log("На диве произошло событие click");
});
Создаём переменные myButton и myDiv для кнопки и блока, на кнопке генерируем новое событие event и передаём это событие диву при помощи метода .dispatchEvent.
Для дива добавляем обработчик событий и прописываем там какой-нибудь код, чтобы отслеживать наступление события. Теперь при клике по кнопке наблюдаем срабатывание обработчика события клик на диве.
Эта возможность используется не так часто, но о её существовании полезно знать.
События мыши
mousedown нажата кнопка мышиmouseup отпущена кнопка мышиclick клик кнопкой мышиdblclick двойной клик кнопкой мышиmouseover курсор вошел в рамки элементаmouseenter курсор вошел в рамки элемента (событие не всплывает)
mousemove курсор двигается над поверхностью элементаmouseout курсор вышел за рамки элементаmouseleave курсор вышел за рамки элемента (событие не всплывает)contextmenu вызов контекстного меню правой кнопкой мышиwheele вращение колеса мыши (имеет разные реализаци в браузерах)
Если, например, нужно реализовать метод drag-and-drop. вначале обрабатываем событие mousedown (нажата кнопка мыши), затем mousemove (передвижение мыши), затем mouseup (отпущена кнопка мыши).
Делегирование
html-код кнопка и ненумерованый список:<button id="myButton">Нажми</button>
<ul id="myList"></ul>
Скрипт:
const myButton = document.querySelector("#myButton");
const myList = document.querySelector("#myList");
let count = 1;
myButton.addEventListener("click", () => {
const li = document.createElement("li");
li.textContent = "элемент " + count++;
myList.appendChild(li);
});
При клике по кнопке создаётся новый элемент списка li, ему добавляем текст, сам элемент li добавляем в список. Всё работает.
Теперь предположим, что каждому элементу списка мы хотим добавить обработчик событий addEventListener. Собственно, можно сделать так:
myButton.addEventListener("click", () => {
const li = document.createElement("li");
li.textContent = "элемент " + count++;
li.addEventListener("click", (event) => {
console.log("кликнули на элемент списка " + event.target.textContent)
});
myList.appendChild(li);
});
И это работает. Но так делать не нужно. для таких случаев предназначено делегирование, когда события на потомках обрабатывает их родитель.
Вот как выглядит нужный нам код:
myList.addEventListener("click", (event) => {
console.log("кликнули на элемент списка " + event.target.textContent);
});
myButton.addEventListener("click", () => {
const li = document.createElement("li");
li.textContent = "элемент " + count++;
myList.appendChild(li);
});
Вместо того, чтобы добавлять обработчик событий на каждый дочерний элемент, мы повесили тот же самый обработчик на их родителя. При помощи event.target мы получили ссылку на элемент, на котором произошло событие. И код работает. Только теперь вместо множества обработчиков на дочерних элементах у нас всего один обработчик на родителе.
При делегировании рекомендуется родительскому элементу добавлять условие, чтобы убедиться, что кликнули именно по дочернему элементу. примерно так:
myList.addEventListener("click", (event) => {
if(event.target.tagName === "LI") {
console.log("кликнули на элемент списка " + event.target.textContent);
}
});
Делегирование - процесс, при котором родительский элемент обрабатывает
все или некоторые события, предназначенные для его потомков.
При таком подходе, нет смысла назначать обработчики на элементы-потомки.
Можно даже запретить потомкам получать события, при помощи методаstopPropagation в обработчике родительского элемента.
Чаще всего используется в целях оптимизации.