закрытие модала в окне vanilla js

#javascript #css

#javascript #css

Вопрос:

Я пытался выяснить, как закрыть модал, который я создал, щелкнув по окну, но безуспешно. Мой модальный активируется путем добавления класса и удаления класса ‘show-modal’. Итак, я создал прослушиватель событий window, и кажется, что всякий раз, когда я нажимаю тег «a» в моем HTML, он также рассматривает этот щелчок как часть окна, поэтому модальное окно даже не открывается.

Однако, как только я удаляю прослушиватель событий window, модал работает нормально; но модал не закрывается, пока я не нажму кнопку «closeModal».

Есть ли что-то, что я делаю неправильно или улучшаю? Я пытался поискать в Google, но их идея отличается от моей.

Я знаю, что могу сделать это с помощью React amp; Boostrap, но я также пытаюсь изучить ванильный способ JS, поэтому я хочу сделать это правильно!

 const contact = document.querySelector('.contact');
const modal = document.querySelector('.modal');
const closeModal = document.querySelector('.closeBtn');

contact.addEventListener('click', showModal);
closeModal.addEventListener('click', modalClose);
window.addEventListener('click', modalClose);

function showModal(){
    modal.classList.add('show-modal');
    console.log('clicked')
}

function modalClose(){
    modal.classList.remove('show-modal');
    console.log('closed')
}


 

Комментарии:

1. Что ты гуглил?

2. @FSDford например, это придумал techstacker.com/close-modal-click-outside-vanilla-javascript .. не устраняет ни мою проблему, ни пример W3schools.

Ответ №1:

Одним из способов обойти это было бы добавить «подложку» к модальному и прослушивать клики по нему вместо элемента window.

Также мне нравится добавлять модальный открытый класс body , чтобы было легко настроить стиль как для модального, так и для модального подложки.

 document.querySelector('button#open').addEventListener('click', e => {
  document.body.classList.add('show-modal')
})

document.querySelector('button#close').addEventListener('click', e => {
  document.body.classList.remove('show-modal')
})

document.querySelector('.underlay').addEventListener('click', e => {
  document.body.classList.remove('show-modal')
}) 
 .modal {
  height: 100px;
  width: 100px;
  background-color: white;
  display: none;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.underlay {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

.show-modal .modal {
  display: block;
}

.show-modal .underlay {
  display: block;
} 
 <button id="open">Open Modal</button>
<div class="underlay"></div>
<div class="modal">
  <button id="close">Close Modal</button>
</div>
</div> 

Комментарии:

1. Спасибо за идею, я на самом деле создал класс .modal в качестве своего наложения, поэтому я просто добавил к нему прослушиватель событий, когда появляется модальное окно .. наложение также находится за ним, так что это становится препятствием, на которое нужно нажать, чтобы отменить применение класса.

Ответ №2:

Вы можете использовать event.stopPropagation(), чтобы избежать распространения событий, попробуйте это:

 function showModal(){
    event.stopPropagation();
    modal.classList.add('show-modal');
    console.log('clicked')
} 

Комментарии:

1. Мне нравится идея; у предыдущего пользователя был хороший способ продемонстрировать логику, поскольку я создаю целевую страницу своего портфолио для подключения к другим проектам. НО с вашей стороны не тратится никаких усилий, это будет отличным расширенным ярлыком для в будущем. Спасибо, @sonEtLumiere