Модальное диалоговое окно должно показываться поверх документа с которым будет запрещено что-либо делать до тех пор, пока диалог не будет завершён и закрыт. Начнём.
HTML разметка
<div class="modal-container">
<div class="modal-content">
<button class="close">Закрыть</button>
<p>Много контента для скролла</p>
</div>
</div>
Контейнер
Начнем с элемента контейнера. Это будет div
, растянутый по ширине и высоте документа в браузере поверх всего приложения, чтобы запретить пользователю делать что-либо с контентом в приложении: выделять текст, кликать по кнопкам, ссылкам и т.д.
.modal-container {
position: fixed;
left: 0;
top: 0;
display: flex;
width: 100vw;
height: 100vh;
padding: 30px;
background-color: rgba(0, 0, 0, 0.5);
}
Добавим position: fixed
, чтобы контейнер всегда был в поле зрения.
Для центрирования содержимого модального окна по горизонтали и вертикали будем использовать display: flex; justify-content: center; align-items: center;
.
Контент
Теперь элемент для содержимого диалогового окна. Это собственно и есть модальное окно, которое будет располагаться в центре экрана.
.modal-content {
overflow: scroll;
width: 100%;
height: 100%;
max-width: 500px;
max-height: 400px;
background-color: #fff;
}
Обратите внимание, что вместо width
и height
используются max-width
и max-height
. Это для того, чтобы модальное окно работало и на небольших экранах. Если вместо этого использовать width: 500px;
, то на мобильных устройствах будет горизонтальная полоса прокрутки.
Кнопка “закрыть”
Последний шаг для завершения модального окна – это стилизация кнопки для его закрытия. Поместим кнопку в правый верхний угол.
.close {
position: absolute;
right: 0;
top: 0;
width: 30px;
height: 30px;
}
Добавление модальной функциональности с помощью Javascript
Модальное окно уже начинает хорошо выглядеть. Следующий шаг – добавление некоторой функциональности, вот наши требования:
- Должна быть возможность открывать и закрывать окно.
- Когда модальное окно открыто, нужно отключить прокрутку в родительском приложении.
Выберем интерактивные элементы
Чтобы переключать режим модального окна, начнём с определения интерактивных элементов.
var modal = document.querySelector('.modal-container');
var closeButton = document.querySelector('.close');
var modalTriggers = document.querySelectorAll('[data-trigger]');
Модальное окно не должно отображаться при инициализации приложения. Позаботимся об этом, добавив следующие css-свойства модальному контейнеру.
.modal-container {
pointer-events: none;
opacity: 0;
}
А также, добавим новый класс, который будет показывать модальное окно.
.modal-container.is-open {
pointer-events: all;
opacity: 1;
}
Добавим перехватчики событий
Теперь, когда модальное окно по умолчанию скрыто, можно добавить функциональность кнопкам закрытия и открывания.
var openModal = function() {
modal.classList.add('is-open')
}
var closeModal = function() {
modal.classList.remove('is-open')
}
modalTriggers.forEach(function(item) {
item.addEventListener('click', openModal)
})
closeButton.addEventListener('click', closeModal)
Теперь можно переключать видимость модального окна.
Отключение скролла в родительском приложении
И последнее, но не менее важное: посмотрим, как отключить прокрутку в родительском приложении, когда модальное окно открыто.
Простейший способ отключить скролл – сохранить позицию прокрутки родительского приложения перед открыванием модального окна. Затем надо добавить в документ перехватчик событий скролла и устанавливать положение прокрутки в сохраненное положение каждый раз, когда пользователь пытается скроллить родительское приложение:
var isModalOpen = false;
var pageYOffset = 0;
var openModal = function() {
...
isModalOpen = true;
pageYOffset = window.pageYOffset;
}
var closeModal = function() {
...
isModalOpen = false;
}
var onScroll = function(e) {
if (isModalOpen) {
window.scrollTo(0, pageYOffset);
}
}
document.addEventListener('scroll', onScroll);
Вот и всё!