Как правильно удалять события с элементов?

У меня есть модальное окно с формой и отдельная кнопка (дальше closeButton). При открытии модального окна я вешаю событие на closeButton, событие, которое закрывает модальное окно. После закрытия окна, я хочу, чтобы событие удалялось с кнопки. Если просто открывать и закрывать модальное окно, то событие с closeButton удаляется, но, если отправить форму, то события копятся на closeButton. Почему cобытия в одном случае копятся, а в другом поведение какое я ожидаю: добавляется одно события и после закрытия оно удаляется. Кнопка формы вызывает ту же функцию, что closeButton, но там почему-то событие не удаляется с closeButton.

введите сюда описание изображения

const button = document.querySelector('.btn');


const container = document.querySelector(".container");

button.addEventListener('click', () => {
  container.style.display = "block"
  
  const closeButton = container.querySelector(".container__close");
  closeButton.addEventListener("click", close(container))
})


const form = container.querySelector("#form");
form.addEventListener('submit', close(container))


function close(elem) {
  const closeButton = elem.querySelector(".container__close");
 
  
  return function func (evt) {
    evt.preventDefault();
    
    elem.style.display = 'none';
    closeButton.removeEventListener('click', func);
  }
}
.btn {
  margin-block-end: 15px;
}

.container {
  display: none;
  inline-size: 500px;
  padding: 15px;
  border: 5px black solid;
}

.container__close {
  inline-size: 100px;
  margin-block-end: 15px;
}
  <button class="btn">Click</button>
  <div class="container" >
      <button type="button" class="container__close">X</button>
      <form id="form">
        <input type="text" placeholder="Имя" required>
        <input type="text" name="description" placeholder="Фамилия" >
        <button type="submit" class="button">Сохранить</button>
      </form>
    </div>


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

Автор решения: Grundy

Функция close возвращает новую функцию при вызове.

На кнопку closeButton обработчик добавляется при клине на кнопку button.

В вызове

form.addEventListener('submit', close(container))

новая функция, созданная внутри close добавляется в качестве обработчика события формы. Она никак не связана с обработчиком добавленным кнопке закрыть.

Поэтому при попытке убрать обработчик - идет проверка, что такого обработчика у кнопки не было - поэтому ничего не происходит.

Для решения можно просто сохранить созданную функцию в переменную:

const button = document.querySelector('.btn');


const container = document.querySelector(".container");

const closeHandler = close(container);
button.addEventListener('click', () => {
  container.style.display = "block"

  const closeButton = container.querySelector(".container__close");
  closeButton.addEventListener("click", closeHandler)
})


const form = container.querySelector("#form");
form.addEventListener('submit', closeHandler)


function close(elem) {
  const closeButton = elem.querySelector(".container__close");


  return function func(evt) {
    evt.preventDefault();

    elem.style.display = 'none';
    closeButton.removeEventListener('click', func);
  }
}
.btn {
  margin-block-end: 15px;
}

.container {
  display: none;
  inline-size: 500px;
  padding: 15px;
  border: 5px black solid;
}

.container__close {
  inline-size: 100px;
  margin-block-end: 15px;
}
<button class="btn">Click</button>
<div class="container">
  <button type="button" class="container__close">X</button>
  <form id="form">
    <input type="text" placeholder="Имя" required>
    <input type="text" name="description" placeholder="Фамилия" >
    <button type="submit" class="button">Сохранить</button>
  </form>
</div>

→ Ссылка