JavaScript. Создание модального окна

27.03.2022

Теги: CSSFrontendHTMLJavaScriptWeb-разработкаПрактика

Модальное окно — элемент интерфейса, которой визуально представляет собой «всплывающее окно», отображающееся над остальной частью страницы. При этом показ окна обычно сопровождают затемнением всей прочей части страницы. Это позволяет визуально отделить его от остального содержимого страницы, а также показать, что в данный момент только оно одно является активным элементом.

Заготовка для показа на странице модального окна:

<!-- Кнопка открытия модального окна -->
<button id="myBtn">Открыть окно</button>

<!-- Затемнение всей страницы при открытии окна -->
<div id="myModal" class="modal">
    <!-- Содержимое модального окна -->
    <div class="modal-content">
        <span class="close">&times;</span>
        <p>Контент модального окна</p>
    </div>
</div>
/* Затемнение всей страницы при открытии окна */
.modal {
    display: none;
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto; /* разрешаем прокрутку */
    background-color: rgba(0,0,0,0.4);
}

/* Добавляется при открытии окна */
.modal-open {
    display: block;
}

/* Содержимое модального окна */
.modal-content {
    background-color: #fefefe;
    margin: 15% auto; /* отступ сверху и центрирование по горизонтали */
    padding: 20px;
    border: 1px solid #888;
    width: 80%;
}

/* Кнопка закрытия модального окна */
.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}
document.addEventListener('DOMContentLoaded', function() {
    // это то модальное окно, с которым и будем работать
    const modal = document.querySelector('#myModal');
});

Добавляем обработчик клика по кнопке открытия модального окна:

document.addEventListener('DOMContentLoaded', function() {
    // это то модальное окно, с которым и будем работать
    const modal = document.querySelector('#myModal');

    // назначаем обработчик события для клика по кнопке открытия окна
    document.querySelector('#myBtn').addEventListener('click', openModal);

    /*
     * Обработчик события клика по кнопке открытия модального окна
     */
    function openModal() {
        modal.classList.add('modal-open');
        // обработчики событий, которые работают, когда окно открыто
        attachModalEvents();
    }
});

В момент открытия окна добавляем обработчики событий, которые должны отрабатывать, когда окно находится в открытом состоянии:

document.addEventListener('DOMContentLoaded', function() {
    // это то модальное окно, с которым и будем работать
    const modal = document.querySelector('#myModal');

    // назначаем обработчик события для клика по кнопке открытия окна
    document.querySelector('#myBtn').addEventListener('click', openModal);

    /*
     * Обработчик события клика по кнопке открытия модального окна
     */
    function openModal() {
        modal.classList.add('modal-open');
        // обработчики событий, которые работают, когда окно открыто
        attachModalEvents();
    }

    /*
     * Функция назначает обработчики событий к элементам модального окна при открытии
     */
    function attachModalEvents() {
        // закрывать модальное окно при нажатии на крестик
        modal.querySelector('.close').addEventListener('click', closeModal);
        // закрывать модальное окно при нажатии клавиши Escape
        document.addEventListener('keydown', handleEscape);
        // закрывать модальное окно при клике вне контента модального окна
        modal.addEventListener('click', handleOutside);
    }
});

При клике на крестик внутри модального окна — окно должно быть закрыто и удалены все добавленные при открытии обработчики событий:

document.addEventListener('DOMContentLoaded', function() {
    // это то модальное окно, с которым и будем работать
    const modal = document.querySelector('#myModal');

    // назначаем обработчик события для клика по кнопке открытия окна
    document.querySelector('#myBtn').addEventListener('click', openModal);

    /*
     * Обработчик события клика по кнопке открытия модального окна
     */
    function openModal() {
        modal.classList.add('modal-open');
        // обработчики событий, которые работают, когда окно открыто
        attachModalEvents();
    }

    /*
     * Функция назначает обработчики событий к элементам модального окна при открытии
     */
    function attachModalEvents() {
        // закрывать модальное окно при нажатии на крестик
        modal.querySelector('.close').addEventListener('click', closeModal);
        // закрывать модальное окно при нажатии клавиши Escape
        document.addEventListener('keydown', handleEscape);
        // закрывать модальное окно при клике вне контента модального окна
        modal.addEventListener('click', handleOutside);
    }

    /*
     * Обработчик события клика по кнопке закрытия модального окна
     */
    function closeModal() {
        modal.classList.remove('modal-open');
        // окно закрыто, эти обработчики событий больше не нужны
        detachModalEvents();
    }

    /*
     * Функция удаляет обработчики событий к элементам модального окна при закрытии
     */
    function detachModalEvents() {
        modal.querySelector('.close').removeEventListener('click', closeModal);
        document.removeEventListener('keydown', handleEscape);
        modal.removeEventListener('click', handleOutside);
    }
});

Почти все готово, осталось написать две функции, которые упоминаются в коде, но еще не реализованы:

/*
 * Функция закрывает модальное окно при нажатии клавиши Escape
 */
function handleEscape(event) {
    if (event.key === 'Escape') {
        closeModal();
    }
}
/*
 * Функция закрывает модальное окно при клике вне контента модального окна
 */
function handleOutside(event) {
    const isClickInside = !!event.target.closest('.modal-content');
    if (!isClickInside) {
        closeModal();
    }
}

И в заключение — полный код примера модального окна:

<!DOCTYPE html>
<html lang="ru">
<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">
    <title>Модальное окно</title>
    <style>
        /* Затемнение всей страницы при открытии окна */
        .modal {
            display: none;
            position: fixed;
            z-index: 1;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            overflow: auto; /* разрешаем прокрутку */
            background-color: rgba(0,0,0,0.4);
        }

        /* Добавляется при открытии окна */
        .modal-open {
            display: block;
        }

        /* Содержимое модального окна */
        .modal-content {
            background-color: #fefefe;
            margin: 15% auto; /* отступ сверху и центрирование по горизонтали */
            padding: 20px;
            border: 1px solid #888;
            width: 80%;
        }

        /* Кнопка закрытия модального окна */
        .close {
            color: #aaa;
            float: right;
            font-size: 28px;
            font-weight: bold;
        }

        .close:hover,
        .close:focus {
            color: black;
            text-decoration: none;
            cursor: pointer;
        }
    </style>
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // это то модальное окно, с которым и будем работать
            const modal = document.querySelector('#myModal');

            // назначаем обработчик события для клика по кнопке открытия окна
            document.querySelector('#myBtn').addEventListener('click', openModal);

            /*
             * Обработчик события клика по кнопке открытия модального окна
             */
            function openModal() {
                modal.classList.add('modal-open');
                // обработчики событий, которые работают, когда окно открыто
                attachModalEvents();
            }

            /*
             * Функция назначает обработчики событий к элементам модального окна при открытии
             */
            function attachModalEvents() {
                // закрывать модальное окно при нажатии на крестик
                modal.querySelector('.close').addEventListener('click', closeModal);
                // закрывать модальное окно при нажатии клавиши Escape
                document.addEventListener('keydown', handleEscape);
                // закрывать модальное окно при клике вне контента модального окна
                modal.addEventListener('click', handleOutside);
            }

            /*
             * Обработчик события клика по кнопке закрытия модального окна
             */
            function closeModal() {
                modal.classList.remove('modal-open');
                // окно закрыто, эти обработчики событий больше не нужны
                detachModalEvents();
            }

            /*
             * Функция удаляет обработчики событий к элементам модального окна при закрытии
             */
            function detachModalEvents() {
                modal.querySelector('.close').removeEventListener('click', closeModal);
                document.removeEventListener('keydown', handleEscape);
                modal.removeEventListener('click', handleOutside);
            }

            /*
             * Функция закрывает модальное окно при нажатии клавиши Escape
             */
            function handleEscape(event) {
                if (event.key === 'Escape') {
                    closeModal();
                }
            }

            /*
             * Функция закрывает модальное окно при клике вне контента модального окна
             */
            function handleOutside(event) {
                const isClickInside = !!event.target.closest('.modal-content');
                if (!isClickInside) {
                    closeModal();
                }
            }
        });
    </script>
</head>
<body>
    <!-- Кнопка открытия модального окна -->
    <button id="myBtn">Открыть окно</button>

    <!-- Затемнение всей страницы при открытии окна -->
    <div id="myModal" class="modal">
        <!-- Содержимое модального окна -->
        <div class="modal-content">
            <span class="close">&times;</span>
            <p>Контент модального окна</p>
        </div>
    </div>
</body>
</html>

Поиск: CSS • Frontend • HTML • JavaScript • Web-разработка • Практика

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.