Попап на чистом JS. Модальное окно без jQuery

Приветствую, друзья, сегодня я покажу, как создать попап на чистом js. В данном всплывающем окне вы можете разместить что угодно. Например, форму для обратной связи (как в данном примере) или любой другой контент. Так же мы реализуем несколько способов скрытие модального окна. Первый способ — скрытие попап окна при клике на фон, а второй — при клике на крестик. Пример того, что вы получите в итоге, можно посмотреть по ссылке на codepen.

HTML-структура модального окна

Для начала создадим HTML разметку для нашего всплывающего окна на чистом JavaScript. Тут все достаточно просто, так что я просто размещу код. Единственное, что стоит упомянуть — вы можете вместо формы разместить любой HTML код.

<div class="popup__bg"> 
    <form class="popup">
        <img src="images/close.svg" class="close-popup">
        <label>
            <input type="text" name="name">
            <div class="label__text">
                Ваше имя
            </div>
        </label>
        <label>
            <input type="tel" name="tel">
            <div class="label__text">
                Ваш телефон
            </div>
        </label>
        <label>
            <textarea name="message"></textarea>
            <div class="label__text">
                Ваше сообщение
            </div>
        </label>
        <button type="submit">Отправить</button>
    </form>
</div>  

Так же вам нужно добавить кнопку, при клике на которую нужно открывать окно. В моем случае, это тег <a> с классом ‘open-popup’.

<a href="#" class="open-popup">Открыть попап</a>

Стилизация всплывающего окна на чистом JS

Далее необходимо стилизовать наш попап на чистом js. CSS код так же достаточно простой. Большинство кода это вовсе стилизация формы, которая никак не влияет на само окно. Важный код для урока я вынесу в самое начало вставки с кодом. Так же я отмечу её с помощью комментариев.

/* Важная часть */
.popup__bg {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background: rgba(0,0,0,0.5);
    opacity: 0; // Скрываем фон и сам попап
    pointer-events: none; // Запрещаем ему быть целью событий
    transition: 0.5s all;
}

.popup__bg.active { // При добавлении класса 'active'
    opacity: 1; // Показываем фон и попап
    pointer-events: all; // Возвращаем события
    transition: 0.5s all;
}

.popup {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0); // Центрируем и масштабируем в 0 само окно
    background: #fff;
    width: 400px;
    padding: 25px;
    transition: 0.5s all;
}

.popup.active { // При добавлении класса 'active'
    transform: translate(-50%, -50%) scale(1); // Так же центрируем и плавно увеличиваем
    transition: 0.5s all;
}
/* Конец важной части */
/* Далее код для стилизации формы */
.close-popup {
    position: absolute;
    top: 10px;
    right: 10px;
    cursor: pointer;
}

.popup label {
    width: 100%;
    margin-bottom: 25px;
    display: flex;
    flex-direction: column-reverse;
}

.popup .label__text {
    font-size: 14px;
    text-transform: uppercase;
    font-weight: 500;
    color: #cfd0d3;
    margin-bottom: 5px;
}

.popup input {
    height: 45px;
    font-size: 18px;
    border: none;
    outline: none;
    border-bottom: 1px solid #cfd0d3;
}

.popup input:focus {
    border-bottom: 1px solid #2982ff;
}

.popup input:focus + .label__text {
    color: #2982ff;
}

.popup textarea {
    resize: none;
    width: 100%;
    height: 150px;
    border: none;
    outline: none;
    border-bottom: 1px solid #cfd0d3;
    font-size: 18px;
    padding-top: 5px;
}

.popup textarea:focus {
    border-bottom: 1px solid #2982ff;
}

.popup textarea:focus + .label__text {
    color: #2982ff;
}

.popup button {
    width: 100%;
    height: 45px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 18px;
    border: 2px solid #2982ff;
    background: #2982ff;
    cursor: pointer;
    text-transform: uppercase;
    transition: 0.5s all;
}

.popup button:hover {
    background: #fff;
    color:#2982ff;
    transition: 0.5s all;
}

Показ всплывающего окна при клике

Теперь переходим к самому интересному. Будем писать JavaScript код для модального окна. Для начала, создадим переменные, в которые мы поместим все DOM-елементы, которые нам понадобятся в будущем.

let popupBg = document.querySelector('.popup__bg'); // Фон попап окна
let popup = document.querySelector('.popup'); // Само окно
let openPopupButtons = document.querySelectorAll('.open-popup'); // Кнопки для показа окна
let closePopupButton = document.querySelector('.close-popup'); // Кнопка для скрытия окна

Далее напишем код, для появления модального окна на чистом JavaScript. Для начала, нужно повесить обработчик события клика (addEventListener) на каждую кнопку открытия окна. При клике — указываем, что для фона и для самого окна нужно добавить класс ‘active’. А так же предотвращаем стандартное поведение браузера, что бы при клике на ссылку браузер не прыгал вверх странички.

openPopupButtons.forEach((button) => { // Перебираем все кнопки
    button.addEventListener('click', (e) => { // Для каждой вешаем обработчик событий на клик
        e.preventDefault(); // Предотвращаем дефолтное поведение браузера
        popupBg.classList.add('active'); // Добавляем класс 'active' для фона
        popup.classList.add('active'); // И для самого окна
    })
});

Скрытие попап окна при клике на крестик

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

closePopupButton.addEventListener('click',() => { // Вешаем обработчик на крестик
    popupBg.classList.remove('active'); // Убираем активный класс с фона
    popup.classList.remove('active'); // И с окна
});

Прячем попап окно на чистом js при клике на фон

Теперь разберемся как спрятать попап при клике на фон. Нужно повесить обработчик клика на весь документ. Далее необходимо передать событие (е). Если цель события (клик) — это фон окна, то мы так же убираем активные классы с фона и окна.

document.addEventListener('click', (e) => { // Вешаем обработчик на весь документ
    if(e.target === popupBg) { // Если цель клика - фот, то:
        popupBg.classList.remove('active'); // Убираем активный класс с фона
        popup.classList.remove('active'); // И с окна
    }
});

Спасибо, что прочитали. Если у вас остались вопросы — задавайте их в Telegram-канале или в комментариях на YouTube. Так же буду благодарен, если вы прочитаете другие мои статьи:

  1. Стилизация checkbox. Кастомные чекбоксы
  2. Анимированный блик на чистом CSS