JSFiddle - React, Tailwind, and code Playground
by annndrewww
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<title>Modal Window</title>
</head>
<body>
<div class="wrap">
<h1 class="title">JavaScript Modal Window</h1>
<a href="#" data-hystmodal="#myModal">Open window</a>
<!-- Modal window -->
<div class="hystmodal" id="myModal" aria-hidden="true" >
<div class="hystmodal__wrap">
<div class="hystmodal__window" role="dialog" aria-modal="true" >
<button data-hystclose class="hystmodal__close">Close</button>
<h1>Заголовок модального окна</h1>
<p>Текст модального окна ...</p>
<p>Ещё текст модального окна ...</p>
</div>
</div>
</div>
<!-- Modal Window end -->
</div>
<div class="modal-shadow"></div>
<script src="app.js"></script>
</body>
</html>
CSS
/* settings */
ul {
list-style: none;
}
/* Modal window */
.wrap {
max-width: 1110px;
margin: auto;
padding: 30px 0;
}
.title {
text-align: center;
font-size: 60px;
}
.hystmodal {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
display: flex;
flex-flow: column nowrap;
justify-content: center; /* см. ниже */
align-items: center;
z-index: 99;
visibility: hidden;
/* Чтобы окно не прилипало к границе
браузера установим отступы */
padding:30px 0;
background-color: rgba(0, 0, 0, .5);
}
.hystmodal__window {
border-radius: 10px;
padding: 20px;
margin: 50px 0;
flex-shrink: 0;
flex-grow: 0;
background: #fff;
width: 600px;
max-width: 100%;
overflow: visible;
transition: transform 0.2s ease 0s, opacity 0.2s ease 0s;
transform: scale(0.9);
opacity: 0;
}
.hysmodal__wrap {
flex-shrink: 0;
flex-grow: 0;
width: 100%;
min-height: 100%;
margin: auto;
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
}
.btns {
display: flex;
justify-content: flex-end;
}
.hystmodal__close {
font-size: 20px;
border: none;
padding: 9px 22px;
border-radius: 15px;
transition: .1s linear;
}
.hystmodal__close:hover {
background-color: rgba(0, 0, 0, 0.1);
}
/* Modal active */
.hystmodal--active{
visibility: visible;
}
.hystmodal--active .hystmodal__window {
transform: scale(1);
opacity: 1;
}
.hystmodal__shadow {
position: fixed;
border:none;
display: block;
width: 100%;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
pointer-events: none;
z-index: 98;
opacity: 0;
transition: opacity 0.15s ease;
background-color: black;
}
.hystmodal__shadow--show{
pointer-events: auto;
opacity:...
JavaScript
// Находим тег html и сохраняем его
let html = document.documentElement;
//сохраним текущую прокрутку:
let scrollPosition = window.pageYOffset;
//установим свойство top у html равное прокрутке
html.style.top = -scrollPosition + "px";
html.classList.add("hystmodal__opened");
html.classList.remove("hystmodal__opened");
//прокручиваем окно туда где оно было
window.scrollTo(0, scrollPosition);
html.style.top = "";
class HystModal{
/**
* При создании экземпляра класса, мы передаём в него
* js-объект с настройками. Он становится доступен
* в конструкторе класса в виде переменной props
*/
constructor(props){
/**
* Для удобства некоторые свойства можно не передавать
* Мы должны заполнить их начальными значениями
* Это можно сделать применив метод Object.assign
*/
let defaultConfig = {
linkAttributeName: 'data-hystmodal',
// ... здесь остальные свойства
}
this.config = Object.assign(defaultConfig, props);
// сразу вызываем метод инициализации
this.init();
}
/**
* В свойство _shadow будет заложен div с визуальной
* подложкой. Оно сделано статическим, т.к. при создании
* нескольких экземпляров класса, эта подложка нужна только
* одна
*/
static _shadow = false;
init(){
/**
* Создаём триггеры состояния, полезные переменные и.т.д.
*/
this.isOpened = false; // открыто ли окно
this.openedWindow = false; //ссылка на открытый .hystmodal
this._modalBlock = false; //ссылка на открытый .hystmodal__window
this.starter = false, //ссылка на элемент "открыватель" текущего окна
// (он нужен для возвращения фокуса на него)
this._nextWindows = false; //ссылка на .hystmodal который нужно открыть
this._scrollPosition = 0; //текущая прокрутка (см. выше)
/**
* ... остальное
*/
// Создаём только одну...