Объяснение делегирования событий
Чтобы сделать это очень кратким и лаконичным, Event Bubbling или Event Delegation — это просто шаблон в javascript, который используется для обработки действий, обнаруженных внутри дочерние элементы элемента без индивидуального добавления к ним прослушивателей событий.
Рассмотрим сценарий, в котором у вас есть контейнер div, содержащий 5 кнопок, и каждая из них добавляет число на экран.
<div id="button-container"> <button id="add-one"> 1 </button> <button id="add-two"> 2 </button> <button id="add-three"> 3 </button> <button id="add-four"> 4 </button> <button id="add-five"> 5 </button> </div> <div> <h3 id="display-number"> 0 </h3> </div>
Не применяя концепцию DRY (не повторяйтесь) в javascript, можно добавить прослушиватель событий ко всем кнопкам и вызывать их функции при каждом нажатии.
const displayNumber = document.querySelector("#display-number") const addOneButton = document.querySelector("#add-one"); const addTwoButton = document.querySelector("#add-two"); const addThreeButton = document.querySelector("#add-three"); const addFourButton = document.querySelector("#add-four"); const addFiveButton = document.querySelector("#add-five"); addOne.addEventlistener("click", () => { displayNmber.textContent += 1 }) addTwo.addEventlistener("click", () => { displayNmber.textContent += 2 }) addThree.addEventlistener("click", () => { displayNmber.textContent += 3 }) addFour.addEventlistener("click", () => { displayNmber.textContent += 4 }) addFive.addEventlistener("click", () => { displayNmber.textContent += 5 })
Что-то не так с подходом выше?
Ну, короткий ответ - Нет.
Но приведенный выше код выглядит избыточным. Что, если бы я сказал вам, что есть способ добавить прослушиватель событий к родительскому элементу, и он будет выполнять функцию по отношению к нажатой кнопке. С делегированием событий мы можем реорганизовать приведенный выше код следующим образом:
<div id="button-container"> <button data-value="1"> 1 </button> <button data-value="2"> 2 </button> <button data-value="3"> 3 </button> <button data-value-"4"> 4 </button> <button data-value="5"> 5 </button> </div> <div> <h3 id="display-number"> 0 </h3> </div>
И мы можем добавить в код один прослушиватель событий следующим образом:
const container = document.querySelector("#button-container"); const displayNumber = document.querySelector("#display-number"); container.addEventlistener('click', (e) => { const target = e.target const value = target.dataset.value //check if the clicked element has a data attribute with if(value){ displayNumber.textContext = Number(displayNumber.textContent) + value } })
Всего за несколько строк кода мы смогли воспроизвести приведенные выше коды.