Объяснение делегирования событий

Чтобы сделать это очень кратким и лаконичным, 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
    }
})

Всего за несколько строк кода мы смогли воспроизвести приведенные выше коды.