Как создать простое модальное окно на jQuery
Чтобы создать модальное окно на jQuery, соберите плагин из разметки, CSS и обработчиков событий. Готовый пример откроет панель по кнопке, затемнит страницу, заблокирует прокрутку и вернет фокус после закрытия. Вы также добавите закрытие по крестику, затемнению и клавише Esc.
Что мы хотим создать
Плагин откроет сообщение после нажатия на кнопку. Панель окажется в центре экрана, а фон временно станет недоступным для взаимодействия.

Закрыть окно можно тремя способами: нажать кнопку с символом ×, кликнуть по затемнению или нажать Esc. Фокус перейдет внутрь окна при открытии и вернется на кнопку после закрытия.
Подготовьте четыре файла: index.html, jquery.js, modal.css и jquery.paulund_modal_box.js. Полная сборка jQuery нужна для методов анимации. Официальную документацию по библиотеке и ее методам смотрите в jQuery API.
HTML-разметка страницы
Создайте файл index.html и добавьте кнопку вызова. Элемент button не меняет адрес страницы и не требует отмены перехода по href.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Пример модального окна</title>
<link rel="stylesheet" href="modal.css">
</head>
<body>
<main>
<h1>Информация о доставке</h1>
<button type="button" class="paulund_modal">
Открыть сообщение
</button>
</main>
</body>
</html>Откройте сохраненный файл в браузере: на странице появятся заголовок и кнопка.
Создание jQuery-плагина модального окна
Создайте файл jquery.paulund_modal_box.js. Метод в $.fn подключает плагин к объектам jQuery, а $.extend() объединяет параметры вызова со значениями по умолчанию.
Добавьте каркас с вызовом e.preventDefault(), чтобы плагин работал и со ссылкой href="#" без перехода.
(function ($) {
$.fn.paulund_modal_box = function (prop) {
var options = $.extend({
height: 250,
width: 500,
title: 'Информация',
description: 'Заказ готов к отправке.'
}, prop);
return this.off('click.paulundModal')
.on('click.paulundModal', function (e) {
e.preventDefault();
// Здесь появится создание окна.
});
};
})(jQuery);Возврат результата .on() сохраняет цепочку методов jQuery. Пространство имен paulundModal позволяет заменить обработчик при повторной инициализации.
Добавление блокировки страницы
Добавьте в modal.css класс затемнения. Фиксированное позиционирование привязывает слой к окну браузера, а inset: 0 растягивает его до всех границ.
.paulund_block_page {
position: fixed;
inset: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 16px;
background: rgba(0, 0, 0, 0.6);
}
body.paulund_modal_open {
overflow: hidden;
}Flexbox центрирует панель, а отступ 16 px отделяет ее от краев экрана.
При открытии плагин сохранит исходное значение body.style.overflow и установит hidden. После закрытия скрипт вернет сохраненное значение, поэтому страница продолжит прокручиваться.
Создание модального окна
Добавьте в modal.css стили панели, заголовка, текста и кнопки закрытия. Размеры задаются параметрами плагина, а CSS ограничивает панель доступной областью экрана.
.paulund_modal_box {
position: relative;
box-sizing: border-box;
max-width: 100%;
max-height: 100%;
overflow: auto;
padding: 24px;
border: 1px solid #ddd;
border-radius: 10px;
background: #fff;
color: #222;
box-shadow: 0 2px 7px #292929;
}
.paulund_modal_title {
margin: 0 40px 16px 0;
font-size: 24px;
}
.paulund_modal_description {
margin: 0;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.paulund_modal_close {
position: absolute;
top: 8px;
right: 8px;
width: 36px;
height: 36px;
border: 0;
border-radius: 4px;
background: #eee;
color: #222;
font-size: 28px;
line-height: 1;
cursor: pointer;
}
.paulund_modal_close:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}Кнопка содержит символ ×, поэтому отдельное изображение для закрытия не требуется. Атрибут aria-label сообщает скринридеру назначение кнопки. Панель получит role="dialog", aria-modal="true" и связь с заголовком через aria-labelledby.
Добавляйте заголовок и описание методом .text(), который отображает пользовательские данные обычным текстом.
Не передавайте непроверенные пользовательские данные в .html(). Вставка строки как HTML может создать риск XSS.
Готовый jQuery-плагин
Замените каркас в файле jquery.paulund_modal_box.js этим кодом. Стили остаются в отдельном файле, а плагин допускает одно открытое окно одновременно.
(function ($) {
var active = false;
var counter = 0;
$.fn.paulund_modal_box = function (prop) {
var options = $.extend({
height: 250,
width: 500,
title: 'Информация',
description: 'Заказ готов к отправке.'
}, prop);
return this.off('click.paulundModal')
.on('click.paulundModal', function (e) {
e.preventDefault();
if (active) return;
active = true;
var opener = this;
var closing = false;
var body = document.body;
var oldOverflow = body.style.overflow;
var background = [];
var titleId = 'paulund-modal-title-' + (++counter);
var duration = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches ? 0 : 120;
var $overlay = $('<div>', {
'class': 'paulund_block_page'
});
var $dialog = $('<div>', {
'class': 'paulund_modal_box',
role: 'dialog',
'aria-modal': 'true',
'aria-labelledby': titleId,
tabindex: '-1'
}).css({
width: options.width,
height: options.height
});
var $close = $('<button>', {
'class': 'paulund_modal_close',
type: 'button',
'aria-label': 'Закрыть окно'
}).text('×');
var $title = $('<h2>', {
'class': 'paulund_modal_title',
id: titleId
}).text(options.title);
var $description = $('<p>', {
'class': 'paulund_modal_description'
}).text(options.description);
$dialog.append($close, $title, $description);
$overlay.append($dialog).appendTo(body);
Array.from(body.children).forEach(function (element) {
if (element === $overlay[0]) return;
background.push({
element: element,
inert: element.inert
});
element.inert = true;
});
body.style.overflow = 'hidden';
function closeModal() {
if (closing) return;
closing = true;
$overlay.stop(true).fadeOut(duration, function () {
$(document).off('.paulundModalOpen');
$overlay.remove();
background.forEach(function (item) {
item.element.inert = item.inert;
});
body.style.overflow = oldOverflow;
active = false;
if (opener.isConnected) opener.focus();
});
}
$close.on('click.paulundModalClose', closeModal);
$overlay.on('click.paulundModalOverlay', function (event) {
if (event.target === $overlay[0]) closeModal();
});
$(document).on('keydown.paulundModalOpen', function (event) {
if (event.key === 'Escape') {
event.preventDefault();
closeModal();
}
if (event.key === 'Tab') {
event.preventDefault();
$close[0].focus();
}
});
$(document).on('focusin.paulundModalOpen', function (event) {
if (!$dialog[0].contains(event.target)) {
$close[0].focus();
}
});
$overlay.hide().fadeIn(duration);
$close[0].focus();
});
};
})(jQuery);Обработчик закрытия привязан к новой кнопке $close. Проверка event.target закрывает окно только при клике по самому затемнению.
Метод .fadeOut() запускает исчезновение, а колбэк удаляет оверлей после завершения анимации. Флаг closing не дает повторно запустить закрытие.
Плагин удерживает фокус на единственном интерактивном элементе панели – кнопке закрытия.
Для формы или нескольких кнопок список элементов фокуса нужно расширить.
Использование jQuery-плагина
Скачайте полную сборку jQuery на официальной странице jquery.com/download и сохраните файл рядом с index.html под именем jquery.js. Можно использовать уже подключенную на сайте копию, если она содержит методы анимации.
Добавьте скрипты перед закрывающим тегом </body>. Сначала загрузите библиотеку, затем плагин и после него вызов инициализации.
<script src="jquery.js"></script>
<script src="jquery.paulund_modal_box.js"></script>
<script>
$(function () {
$('.paulund_modal').paulund_modal_box();
});
</script>Нажмите «Открыть сообщение». Панель появится по центру, фон потемнеет, прокрутка страницы остановится, а фокус перейдет на крестик.
- Нажмите кнопку закрытия. Панель исчезнет, а фокус вернется на кнопку вызова.
- Откройте окно снова и нажмите Esc. Скрипт закроет панель тем же способом.
- Кликните по затемнению. Окно закроется, а клик внутри белой панели его не закроет.
- Нажмите Tab или Shift+Tab. Фокус останется внутри открытого окна.
- Уменьшите окно браузера. Панель сохранит отступ 16 px от краев экрана.
Ошибка jQuery is not defined означает, что библиотека не загрузилась.
Ошибка paulund_modal_box is not a function указывает на неправильный порядок подключения файлов.
Чтобы убрать компонент, удалите вызов инициализации и подключение плагина. Затем удалите modal.css, если этот файл больше не используют другие элементы страницы.
Использование параметров
Плагин принимает четыре параметра: title, description, height и width. Заголовок и описание задаются строками, размеры – положительными числами в пикселях.
| Параметр | Значение по умолчанию | Что меняет |
|---|---|---|
title | Информация | Заголовок панели |
description | Заказ готов к отправке. | Текст сообщения |
height | 250 | Высоту панели в пикселях |
width | 500 | Ширину панели в пикселях |
Замените вызов инициализации в index.html этим примером. Панель получит ширину 600 px и высоту 320 px, если экран позволяет такой размер.
<script>
$(function () {
$('.paulund_modal').paulund_modal_box({
title: 'Доставка заказа',
description: 'Курьер свяжется с вами перед выездом. Подготовьте номер заказа.',
height: 320,
width: 600
});
});
</script>Свойство white-space: pre-wrap сохраняет переносы строк в описании, а HTML-разметка в параметрах отображается обычным текстом.
Для разных сообщений назначьте кнопкам разные классы и вызовите плагин отдельно для каждой группы. Например, одна кнопка может показывать условия доставки, а другая – информацию об оплате.
Когда использовать встроенный dialog
Для нового проекта рассмотрите встроенный элемент <dialog> и его метод showModal(). Браузер создает модальное состояние, обрабатывает Esc и управляет фокусом.
Псевдоэлемент ::backdrop оформляет затемнение.
Чтобы закрывать окно по фону, обработайте клик и сравните event.target с самим элементом dialog, как в примере с оверлеем.
Проверьте окно клавиатурой до публикации страницы. Esc должен закрывать панель, а фокус возвращаться на кнопку вызова.
Популярное за неделю
- Как создать сайт самому в 2026: 4 способа + пошаговая инструкция 34 мин чтения
- Лучшие конструкторы для создания сайтов — плюсы, минусы и сравнения 22 мин чтения
- Как работает js задержка выполнения через setTimeout 4 мин чтения
- 15 таймеров обратного отсчёта на jQuery и CSS3 2 мин чтения
- 17 бесплатных jQuery‑скриптов для загрузки файлов 5 мин чтения
- Примеры AJAX-запросов с jQuery и PHP 2 мин чтения
Комментарии