Skip to content

Instantly share code, notes, and snippets.

@aau8
Last active May 2, 2022 03:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aau8/520332a79c95c21ce53b824f7f24aa1f to your computer and use it in GitHub Desktop.
Save aau8/520332a79c95c21ce53b824f7f24aa1f to your computer and use it in GitHub Desktop.
Модальное окно
<div class="modal" data-modal-id="modal">
<div class="modal__wrap">
<div class="modal__window">
<button class="modal-close">
<span></span>
<span></span>
</button>
</div>
<div class="modal__bg"></div>
</div>
</div>
modal()
function modal() {
// Открытие модальных окон при клике по кнопке
openModalWhenClickingOnBtn()
function openModalWhenClickingOnBtn() {
window.addEventListener('click', e => {
const target = e.target
if (target.dataset.modalOpen != undefined || target.closest('[data-modal-open]')) {
const btn = target.closest('[data-modal-open]') ? target.closest('[data-modal-open]') : target;
const dataBtn = btn.dataset.modalOpen;
const modal = document.querySelector(`#${dataBtn}`)
window.location.hash = dataBtn
}
})
}
// Открытие модального окна, если в url указан его id
openModalHash()
function openModalHash() {
if (window.location.hash) {
const hash = window.location.hash.substring(1)
const modal = document.querySelector(`.modal[data-modal-id=${hash}]`)
if (modal) openModal(modal)
}
}
// Показываем/убираем модальное окно при изменения хеша в адресной строке
checkHash()
function checkHash() {
window.addEventListener('hashchange', e => {
const hash = window.location.hash.replace('#', '')
const modal = document.querySelector(`.modal[data-modal-id="${hash}"]`)
if (find('.modal._show')) closeModal(find('.modal._show'))
if (modal && hash != '') openModal(modal)
})
}
// Закрытие модального окна при клике по заднему фону
closeModalWhenClickingOnBg()
function closeModalWhenClickingOnBg() {
document.addEventListener('click', (e) => {
const target = e.target
if (target.classList.contains('modal__bg')) {
closeModal(target.closest('.modal'))
}
})
}
// Закрытие модальных окон при клике по крестику
closeModalWhenClickingOnCross()
function closeModalWhenClickingOnCross() {
const modalElems = document.querySelectorAll('.modal')
for (let i = 0; i < modalElems.length; i++) {
const modal = modalElems[i];
const closeThisModal = modal.querySelector('.modal-close')
closeThisModal.addEventListener('click', () => {
closeModal(modal)
})
}
}
// Закрытие модальных окон при нажатии по клавише ESC
closeModalWhenClickingOnESC()
function closeModalWhenClickingOnESC() {
const modalElems = document.querySelectorAll('.modal')
for (let i = 0; i < modalElems.length; i++) {
const modal = modalElems[i];
document.addEventListener('keydown', e => {
if (e.key === 'Escape') closeModal(modal)
})
}
}
// Сброс id модального окна в url
function resetHash() {
const windowTop = window.pageYOffset
window.location.hash = ''
window.scrollTo(0, windowTop)
}
// Открытие модального окна
function openModal(modal) {
modal.classList.add('_show')
bodyLock(true)
}
// Закрытие модального окна
function closeModal(modal) {
modal.classList.remove('_show')
bodyLock(false)
resetHash()
}
}
.modal {
position: fixed;
z-index: 10;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.3);
overflow: hidden;
visibility: hidden;
opacity: 0;
transition: $tr;
&._show {
visibility: visible;
opacity: 1;
overflow-y: auto;
& .modal__wrap {
transform: translate(0, 0);
}
}
}
.modal__bg {
position: absolute;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.modal__wrap {
min-height: 100%;
transform: translate(0, 100vh);
display: flex;
justify-content: center;
align-items: center;
padding: 30px 16px;
transition: $tr;
}
.modal__window {
position: relative;
max-width: 512px;
width: 100%;
background: #fff;
border-radius: $radius-m;
padding: 32px;
@media (max-width: $tablet) {
padding: 32px 24px;
}
@media (max-width: $mobile-l) {
padding: 24px 16px;
}
}
.modal-close {
position: absolute;
top: 16px;
right: 16px;
width: 24px;
height: 24px;
& span {
position: absolute;
top: 50%;
left: 50%;
width: 13.5px;
height: 1.5px;
background: #333;
border-radius: 100px;
&:nth-child(1) {
transform: translate(-50%, -50%) rotate(45deg);
}
&:nth-child(2) {
transform: translate(-50%, -50%) rotate(-45deg);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment