addEventListener для созданного элемента

Всем доброго дня. Пытаюсь разобраться с вызовом модального окна при нажатии на каждом третьем элементе создаваемых блоках и проблема заключается в том, что первое нажатие "игнорируется" и модалка открывается только после повторного нажатия на третий span. Догадываюсь, что addEventListener не знает о существовании создаваемых блоках "заранее" и поэтому первое нажатии игнорируется и модалка не открывается. Можно это как то обойти?

const btn = document.querySelector("#btn");
const modal = document.querySelector("#modal");
const info = document.querySelector(".info");

btn.addEventListener('click', () => {
  info.innerHTML += `<div><span>1</span><span>2</span><span data-del>3</span></div>`
})

info.addEventListener('click', (e) => {
  const target = e.target.closest('[data-del]');
  if (!target) return;
  
  target.addEventListener("click", () => {
    modal.showModal();
  });
})
div {
  width: 100%;
  height: 30px;
}
span {
  display: inline-block;
  width: 50px;
  background-color: aqua;
  margin: 5px;
  text-align: center;
}
.info {
  width: 300px;
}
<button id="btn">Добавить строку</button>
<div class="info"></div>

<dialog id="modal">
  <p>Модальное окно</p>
</dialog>

p.s. с JS знаком поверхностно, так что не исключаю банальных своих ошибок в коде


Ответы (1 шт):

Автор решения: Oliver Patterson

В вашем случае вы уже использовали делегирование

info.addEventListener('click', (e) => {
  const target = e.target.closest('[data-del]');
  if (!target) return;
  // ...
})

... то есть при клике внутри блока, вы проверяете был ли это клик внутри элемента с [data-del]. По этому вам не нужно добавлять слушатель клика на этот элемент.

Готовый код будет таковым:

const btn = document.querySelector("#btn");
const modal = document.querySelector("#modal");
const info = document.querySelector(".info");

btn.addEventListener('click', () => {
  info.innerHTML += `<div><span>1</span><span>2</span><span data-del>3</span></div>`
})

info.addEventListener('click', (e) => {
  const target = e.target.closest('[data-del]');
  if (!target) return;
  
  modal.showModal();
})
div {
  width: 100%;
  height: 30px;
}
span {
  display: inline-block;
  width: 50px;
  background-color: aqua;
  margin: 5px;
  text-align: center;
}
.info {
  width: 300px;
}
<button id="btn">Добавить строку</button>
<div class="info"></div>

<dialog id="modal">
  <p>Модальное окно</p>
</dialog>

→ Ссылка