Как сделать модальное окно javascript

Обновлено: 04.05.2024

Добрый день! Меня зовут Черепанов Борис, я занимаюсь разработкой сайтов на wordpress и bitrix. Я тут над проектом работал. Одно из ограничений было не использовать jquery, а мне нужно было вызвать одно и тоже модальное окно с разных кнопок. Собственно, это довольно простая задача, но я решил пойти дальше и сделать модальное окно, которое бы создавалось при первом клике, сохраняло своё состояние, имело конструктор для вызова и т.д. И в итоге я не пожалел. Объясню почему позже. Я «обернул» это модальное окно в готовое решение, которое можно использовать постоянно.

Установка

Установить такую «модалку» просто. Скачиваете js-файл и подключаете. Он не зависит от каких-то событий или библиотек, так что можете подключать где вам нужно. Вот ссылка на github

Инициализация

На той странице на которой вам нужно вызвать вы пишите в js:

Подробнее о пунктах в объекте

Есть 6 обязательных пунктов:

  • bodyID – это идентификатор блока в котором будет содержаться контент модального окна
  • backgroundLayerID – id затемняющего слоя
  • selector – html атрибут который будет у всех кнопок которые будут вызывать модальное окно
  • selectorValue – значение селектора
  • bntID – id кнопки закрытия модального окна
  • content – текст или html внутри модального окна
  • classListBg, classListBody, classListBtn – массивы классов для затемняющего слоя, основного окна и кнопки закрыть соответственно
  • styleBg, styleBody, btnStyle – объекты со стилями затемняющего слоя, основного окна и кнопки закрыть соответственно

Немного о самом модальном окне

Я уже говорил, что основная задача, которую решает это модальное окно — это вызов с нескольких кнопок. Клик по нескольким кнопка для вызова js это типичный пример делегирования и в XMC (так я назвал своё модальное окно) оно реализовано так:


Соответственно и в конструкторе нужно прописать:


Кстати, в своё время, мне помогла с этим разобраться статья с learn javascript. Ознакомиться с ней будет полезным.

AJAX для формы

В моём «кейсе» необходимо было загружать форму по ajax (эта задача появилась в процессе). Благодаря моему изначальному подходу мне удалось сэкономить не мало времени. Я расширил через прототип.

Вёрстка таких окон сначала кажется простой задачей. Модальные окна можно сделать даже без помощи JS только лишь с помощью CSS, но на практике они оказываются неудобными, и из-за маленьких недочетов модальные окна раздражают посетителей сайта.

В итоге было задумано сделать собственное простое решение.


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

  • Arctic Modal,
  • jquery-modal,
  • iziModal,
  • Micromodal.js,
  • tingle.js,
  • Bootstrap Modal (из библиотеки Bootstrap) и др.

(в статье не рассматриваем решения на базе Frontend-фреймворков)

Несколькими из них я пользовался сам, но почти у всех находил какие-то недостатки. Некоторые из них требуют подключения библиотеки jQuery, которая есть не на всех проектах. Для разработки своего решения, нужно сначала определиться с требованиями.

Что мы ждём от модальных окон? Отвечая на этот вопрос, я основывался на докладе «Знакомьтесь, модальное окно» Анны Селезнёвой, а так-же на относительно старой статье NikoX «arcticModal — jQuery-плагин для модальных окон».

Итак, чтобы нам хотелось видеть?

Дисклеймер: Прежде чем мы рассмотрим подробности, сразу дам ссылку на готовый код получившейся библиотеки (HystModal) на GitHub, а также ссылку на демо+документацию.

Начнём с разметки.

1. Разметка HTML и CSS

1.1. Каркас модальных окон

Как открыть окно быстро? Самое простое решение: разместить всю разметку модального окна сразу в HTML странице. Затем скрывать/показывать это окно при помощи переключения классов CSS.

Набросаем такую разметку HTML (я назвал этот скрипт «hystmodal»):

Сделаем так, чтобы .hystmodal растягивался на всё окно браузера и закрывал собой содержимое страницы. Чтобы этого добиться, установим фиксированное позиционирование в CSS и приравняем свойства top, bottom, left и right к нулю.

В этом коде сделаны ещё две вещи:

  1. Так как мы хотим центрировать окно внутри страницы, превращаем .hystmodal в flex-контейнер с выравниваем его потомков по центру по вертикали и горизонтали.
  2. Окно может быть больше высоты экрана браузера, поэтому мы устанавливаем overflow-y: auto , чтобы при переполнении возникала полоса прокрутки. Также, для сенсорных экранов (в основном для Safari) нам стоит установить свойство -webkit-overflow-scrolling: touch , чтобы сенсорная прокрутка работала именно на этом блоке а не на странице.

Теперь установим стили для самого окна.

Кажется возникли сложности.

Проблема №1. Если высота окна больше высоты окна браузера, то контент окна будет обрезан сверху.


Это возникает из-за свойства justify-content: center . Оно позволяет нам удобно выровнять потомков по основной оси (по вертикали), но если потомок становится больше родителя то часть его становится недоступной даже при прокручиваемом контейнере. Подробнее можно посмотреть на stackoverflow. Решение – установить justify-content: flex-start , а потомку установить margin:auto . Это выровняет его по центру.

Проблема №2. В ie-11 если высота окна больше высоты окна браузера, то фон окна обрезается.

Решение: мы можем установить flex-shrink:0 потомку – тогда обрезки не происходит.

Проблема №3. В браузерах кроме Chrome нет отступа от нижней границы окна (т.е. padding-bottom не сработал).

Сложно сказать баг это браузеров или наоборот соответствует спецификации, но решения два:

  • установить псевдоэлемент ::after после потомка и дать ему высоту вместо padding
  • обернуть элемент в дополнительный блок и дать отступы уже ему.

Воспользуемся вторым методом. Добавим обертку .hystmodal__wrap . Так мы заодно обойдём и проблему №1, а вместо padding у родителя установим margin-top и margin-top у самого .hystmodal__window .

Наш итоговый html:

В код также добавлены некоторые aria и role атрибуты для обеспечения доступности.

Обновленный код CSS для обертки и окна.

1.2 Скрываем окно

Сейчас наше окно всегда видно. Когда говорят о скрытии элементов, первое что приходит на ум это переключать свойство display со значения none до нашего значения flex.

Но этот подход нас не устроит, ведь свойство display не анимируется. Все переходы дочерних элементов, указанные в свойстве transition, работать не будут.

Нам поможет другое свойство visibility:hidden . Оно скроет окно визуально, хотя и зарезервирует под него место. А так как все будущие окна на странице имеют фиксированное
позиционирование – они будут полностью скрыты и не повлияют на остальную страницу. Кроме того, на элементы с visibility:hidden нельзя установить фокус с клавиатуры, а от скрин-ридеров мы уже скрыли окна с помощью атрибута aria-hidden="true" .

Добавим также классы для открытого окна:

1.3 Оформление подложки

В лучшем случае, нам нужен отдельный html-элемент в качестве оверлея. Можно использовать и имеющийся элемент модального окна .hystmodal в качестве оверлея, но тогда анимация на этом элементе (например переход opacity) будет затрагивать и внутренние элементы. В итоге, не получится анимировать разные свойства для окна и оверлея отдельно.

Просто разместим элемент .hystmodal__shadow прямо перед закрывающим . В будущем, сделаем так, чтобы этот элемент создавался автоматически из js при инициализации библиотеки.

1.4 Отключение прокрутки страницы

Когда модальное окна открывается, мы хотим, чтобы страница под ним не прокручивалась.
Самый простой способ этого добиться — повесить overflow:hidden для body или html, когда окно открывается. Однако с этим есть проблема:

Проблема №4. В браузере Safari на iOS страница будет прокручиваться, даже если на тег html или body повешен overflow:hidden .
Решается двумя способами, либо блокированием событий прокрутки (touchmove, touchend или touchsart) из js вида:

Однако при этом блокируется и прокрутка самого модального окна, а также все прокручиваемые блоки внутри окна, если они будут. Требуется дополнительные проверки селекторов из js, что приводит к усложнению кода, поэтому рассмотрим другой вариант.

ps: можно конечно применить библиотеку scroll-lock, в которую заложено это решение, но в статье было решено воспользоваться другим вариантом.

Другое решение – основано частично на CSS. Пусть когда окно открывается, на элемент будет добавляться класс .hystmodal__opened :

Благодаря position:fixed , окно не будет прокручиваться даже в safari, однако здесь тоже не всё гладко:

Проблема №5. При открытии/закрытии окна страница прокручивается в начало.
Действительно, это происходит из-за изменения свойства position, текущая прокрутка окна сбрасывается.

Для решения, нам нужно написать следующий JS (упрощенно):

При открытии:

При закрытии:

Отлично, приступим к JavaScript коду.

2. Код JavaScript

2.2 Каркас библиотеки

Нам нужна совместимость со старыми браузерами включая IE11 поэтому нам нужно выбрать из 2 вариантов кодинга:

  • Разрабатывать на старом стандарте ES5, и использовать только те фичи, которые поддерживают все браузеры.
  • Применить современный синтаксис ES6, но подключить транспайлер Babel, который автоматически преобразует код для всех браузеров и встроит необходимые полифилы.
    Было принято решение использовать второй вариант, с прицелом на будущее.
    Приступим.

Основа нашей библиотеки единственный класс HystModal . Ниже я приведу скелет кода с комментариями, а потом добавим остальной функционал.

Итак, мы описали класс HystModal . Чтобы всё работало, нужно всего лишь подключить наш скрипт и создать экземпляр класса:

Проблема №6: если в браузере есть фиксированный скроллбар (который влияет на ширину страницы), то при открытии/закрытии окна происходит сдвиг контента, когда полоса прокрутки то появляется то пропадает.

Действительно – скроллбар пропадает и контент страницы перераспределяется. Чтобы решить эту проблему, можно добавить отступ справа к тегу html, равный ширине скроллбара когда он пропадает.

Однако ширина скроллбара может быть разной в разных браузерах и операционных системах. Кроме того, скроллбара может не быть на коротких страницах или он может быть плавающим (например, в Chrome на Android). Поэтому ширину нужно вычислять динамически из скрипта.

Дополним метод _bodyScrollControl()

Почему код метода close() упрощён? Дело в том, что просто убирая классы CSS у элементов, мы не можем анимировать закрытие окна.

Проблема №7. При закрытии окна, свойство visibility:hidden применяется сразу и не даёт возможности анимировать закрытие окна.

Причина этого известна: свойство visibility:hidden не анимируется. Конечно, можно обойтись без анимации, но, если она нужна, сделаем следующее.

  • Создадим дополнительный CSS-класс .hystmodal—moved почти такой-же как и .hystmodal--active
  • Затем при закрытии сначала добавим этот класс к окну и повесим обработчик события «transitionend» на модальном окне. Затем удалим класс `.hystmodal—active , таким образом вызывая css-переход. Как только переход завершится, сработает обработчик события «transitionend», в котором сделаем всё остальное и удалим сам обработчик события.

Ниже: новая версия методов закрытия окна:

Вы заметили, что мы создали ещё один метод _closeAfterTransition() и перенесли основную логику закрытия туда. Это нужно, чтобы удалить обработчик события transitionend после закрытия окна, ведь в метод removeEventListener необходимо передать именно ту функцию, которую мы привязывали.

Кроме того, если анимация не будет нужна, можно просто вызвать this._closeAfterTransition() не вешая его на событие.

Как мы помним, внутри addEventListener, this будет указывать на селектор где происходит событие, а не на наш экземпляр класса, поэтому в конструкторе нужно добавить ещё одну строчку для жёсткой привязки метода к this.

2.2 Закрытие окна по клику на оверлей

Нам нужно обработать ещё одно событие – закрытие окна по клику на элемент подложки .hystmodal__wrap . Мы можем повесить обработчик клика на документ для делегирования события как при открытии и проверить что событие произошло на .hystmodal__wrap примерно так:

Это будет работать, но есть один малозаметный недостаток.

Проблема №8. Если кнопку мыши нажать внутри окна, а отпустить за его пределами (над подложкой), окно закрывается.

Представьте, что в окне форма. Вы выделяете текст в поле ввода и случайно двигаете мышь чуть дальше, курсор заходит на подложку и вдруг окно закрывается, всё вдруг пропадает из виду. Не хотелось бы, чтобы так было.

Окно закрывается потому что по спецификации, если нажатие и отпускание мыши были на разных элементах, то событие click сработает на самом ближайшем общем для них элементе, а у нас это как раз .hystmodal__wrap .

Мы могли бы решить это изменением html, добавляя ещё один div сразу после .hystmodal__window и размещая его визуально под окном. Но нам бы не хотелось добавлять лишний пустой div ещё сильнее усложняя разметку.

Мы можем разбить наш addEventListener на два отдельных обработчика: для событий mousedown и mouseup и будем проверять чтобы оба события происходили именно на .hystmodal__wrap . Добавим новые обработчики событий в наш метод eventsFeeler()

2.3 Управление фокусом

У нас заготовлено два метода для управления фокусом: focusContol() для переноса фокуса внутрь окна и обратно при его закрытии, а также focusCatcher(event) для блокирования ухода фокуса из окна.

Решения для фокуса были реализованы аналогично js-библиотеке «Micromodal» (Indrashish Ghosh). А именно:

1. В служебный массив сохраним все css селекторы на которых может быть установлен фокус (свойство помещаем в init()):

2. В методе focusContol() находим первый такой селектор в окне и устанавливаем на него фокус, если окно открывается. Если же окно закрывается – то переводим фокус на this.starter :

3. В методе focusCatcher() находим в окне и превращаем в массив коллекцию всех элементов на которых может быть фокус. И проверяем, если фокус должен был выйти на пределы окна, то вместо этого устанавливаем фокус снова на первый или последний элемент (ведь фокус можно переключать как по Tab так и по Shift+Tab в обратную сторону).

Результирующий код метода focusCatcher:

По сути мы реализовали все необходимое для успешного создания модальных окон, осталось ещё несколько дел:

Проблема №9. В IE11 не работают методы Element.closest() и Object.assign() .

Для поддержки Element.closest, воспользуемся полифилами для closest и matches от MDN.

Можно их вставить просто так, но так как у нас проект всё равно собирается webpack, то удобно воспользоваться пакетом element-closest-polyfill который просто вставляет этот код.

Для поддержки Object.assign , можно воспользоваться уже babel-плагином @babel/plugin-transform-object-assign

3. Заключение и ссылки

Повторяя начало статьи, всё изложенное выше, я оформил в маленькую библиотеку hystModal под MIT-лицензией. Вышло 3 кБ кода при загрузке с gzip. Ещё написал для неё подробную документацию на русском и английском языке.

Что вошло ещё в библиотеку hystModal, чего не было в статье:

  • Настройки (вкл/выкл управление фокусом, варианты закрытия, ожидание анимации закрытия)
  • Коллбеки (функции вызывающиеся перед открытием окна и после его закрытия (в них передаётся объект модального окна))
  • Добавлен запрет на какие-либо действия пока анимация закрытия окна не завершится, а также ожидание анимации закрытия текущего окна перед открытием нового (если окно открывается из другого окна).
  • Оформление кнопки-крестика закрытия в CSS
  • Минификация CSS и JS плагинами Webpack.

Если вам будет интересна эта библиотека, буду рад звёздочке в GitHub, или напишите в Issues о найденных багах. (Особенно большие проблемы, наверное, в грамматике английской версии документации, так как мои знания языка пока на начальном уровне. Связаться со мной также можно в Instagram

В этой статье мы разберемся как создавать модальные окна с помощью javascript.

Модальные окна которые мы сделаем буду универсальны. Для создания модальных окон в дальнейшем вам не нужно будет дописывать что-то в .js файле.

Весь код для копирования в конце статьи.

Вот что получилось в итоге ( это скрин, не кликать :)):

Кнопки открытия окна

План работы скрипта:

  1. Зарегистрировать событие клика на элементы с классом js-open-modal
  2. При клике на кнопку, ищем модальное окно с таким же атрибутом data-modal, добавляем класс .active подложке и этому модальному окну
  3. При клике на крестик удаляем класс у родительского модального окна и подложки

Пишем JavaScript

В начале, повесим на document событие DOMContentLoaded. Это событие сработает когда страница будет загружена.

Затем запишем массив кнопок в переменную используя метод querySelector. Здесь же определим еще 2 переменные: элемент подложки и массив кнопок-крестиков.

Заметьте, modalButtons и CloseButtons мы получаем через querySelectorAll, который возвращает массив, мы сделали это потому что нужно обрабатывать клики по всем кнопка, а вот overlay мы получаем через querySelector, он возвращает один элемент.

В html добавим кнопкам классы .js-open-modal. Мы специально будем использовать новый класс с приставкой js, чтобы не путать стили и интерактивность. Все кто будет работать с кодом увидит, что у класса есть приставка js, значит этот класс используется для интерактивности и его лучше не трогать.

После этого нужно повесить событие клика на каждую кнопку. Для этого мы переберем полученный массив кнопок и повесим обработчик на каждый элемент. Перебирать массив мы будем с помощью forEach:

В переменной item у нас будет храниться текущий элемент цикла. Повесим обработчик на него:

event или e — объект текущего события. В этом объекте хранятся различные методы и данные. При вызове любого события указание аргумента у функции будет ссылаться на этот объект. Зачем нам нужен этот объект? Об этом чуть ниже.

Что нам нужно сделать теперь?

Для начала нужно предусмотреть то, что кнопка, которая вызывает наше модальное окно, может быть ссылкой, кнопкой в форме или другим элементом, который стандартно выполняет какие-то интерактивные действия. Нам нужно отменить эти действия для нормальной работы нашего кода.

Для этого в объекте события есть метод, который предотвращает стандартное действие элемента.

С предотвращением вопрос решили.

У каждой кнопки есть атрибут data-modal, в нем хранится значение, которое находится у модального окна в таком же атрибуте. Наши действия:

  1. Получить значение атрибута текущей кнопки
  2. Найти модальное окно с помощью этого значения

Для того чтобы найти модальное окно, мы пишем определенный селектор, а там где нужно вставить значение, делаем разрыв строки и вставляем значение переменной, соединяя строки используя оператор сложения, в случае со строками, он выполняет их соединение ( конкатенацию).

В итоге получается такой селектор — ‘.modal=[data-modal="значение переменной"]’ , который и находит наше модальное окно.

Давайте добавим нашему окну и подложке класс active.

Напишем стили для классов .active:

Весь javascript код который получился:

Кнопки должны открывать то модальное окно, к которому привязаны. Проверяем:

Осталось написать закрытие окон по клику на крестик. С перебором элементов и созданием события вы уже знакомы.

При клике на крестик нам нужно у этого же элемента найти родителя или деда с классом .modal и удалить у него класс .active.

Готовой функции для перебора родителей элемента нет. Есть метод который позволяет получить родителя, но это ненадежно, так как разметка может поменяться и наш код сломается.

Для таких задач я не буду писать велосипед, а воспользуюсь готовой микро-библиотекой closest. Код библиотеки:

Его нужно подключить в отдельном файле или в этом же файле до нашего кода.

Библиотека создает функцию closest. Используя её мы можем искать элемент, который находится выше по дереву и класс которого совпадает с тем который мы ищем.

В нашем случае мы должны найти родителя с классом .modal и не важно является ли он прямым предком или между них есть еще какие-то элементы.

От нашего крестика мы идем вверх и проверяем родителя на класс .modal, не подошел — берем родителя его родителя и опять проверяем, так до самого конца, до window, пока не найдем интересующий нас элемент. В библиотеке jquery такая функция есть изначально, пишется она так же.

Элемент в консоли

При клике на крестик, код выполнился и мы увидели в консоли родителя или деда нашего крестика, элемент с классом.modal. Теперь мы можем убрать у него активный класс, сразу же уберем его и у подложки.

Теперь вы можете создавать много много модальных окон не изменяя свой js код.

Спасибо за прочтение статьи! Если материал был полезен для тебя — поставь лайк или напиши об этом в комментариях, это займет 1 минуту, это важно для меня. Спасибо!

Если у тебя есть замечания, пожелания, предложения — можешь так же написать их в комментариях. Я рад новым мнениям и критике.

Дополнение

По просьбе читателя добавляю код для закрытия модального окна по кнопке ESC и при клике на темный фон.

Закрытие окна при клике на ESC:

Здесь мы создали событие нажатия на поднятия клавиш. В документе будут проверяться любые клавиши, нажатые пользователем. В функции мы указываем параметр, который отвечает за событие нажатия.

У событий связанных с клавишами, есть свойство keycode, которое хранит код нажатой клавиши. У ESC этот код — 27.

Нам остается проверять при каждом нажатии код клавиши с кодом ESC и если есть совпадение — удаляем класс у активного окна и фона.

Скрытие при нажатии

Ну тут вы уже сами должны уметь. Не читайте дальше и попробуйте сами подумать и написать этот код. Я сделать пару отступов, чтобы вы не подглядывали.

Ладно, подглядывай уже 🙂

Создаем событие клика на overlay, эта переменная создана в самом начале. Потом в функции удаляем у активного модального окна активный класс и делаем тоже самое у фона, на который кликнули, за это отвечает переменная this, если переводить — этот.

То есть при клике на фон, мы говорим: «Удали активный класс у окна и у фона, на который кликнули»

Модальное окно для сайта на чистом CSS и JavaScript

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

При этом показ окна обычно сопровождают затемнением всей другой части страницы. Это действие позволяет визуально отделить его от остального содержимого страницы, а также показать, что в данный момент только оно одно является активным элементом. При этом контент, расположенный под ним, делают недоступным (т.е. пользователь не сможет с ним взаимодействовать пока он не закроет это окно).

Вызов модального окна можно привязать к различным событиям на странице, но в большинстве сценариев это осуществляют при нажатии на кнопку или ссылку.

Изображение модального окна:

Вид модального окна, созданного с помощью JavaScript

Оно состоит из заголовка (хедера), основной части и футера.

В заголовке обычно выводят название окна и элемент, с помощью которого его можно закрыть. В основной части распологают содержимое, а в футере кнопки для выполнения различных действий.

Загрузка и установка модального окна

Проект модального окна расположен на GitHub. Перейти к нему можно по этой ссылке.

Процесс установки модального окна на страницу выполняется посредством подключения к ней его CSS и JavaScript файлов, или добавления их содержимого в соответствующие свои файлы.

Как создать и вызвать модальное окно

Эта реализация модального окна не требует непосредственного размещения его HTML кода на странице . Это выполняется программно.

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

При создании окна вы можете сразу же его настроить, для этого в данную функцию необходимо передать данные в формате объекта. Осуществляется это с помощью соответствующих ключей (свойств). Например, с помощью ключа title вы можете задать заголовок, который будет иметь всплывающее окно по умолчанию. Ключ content позволяет установить содержимое, а footerButtons – кнопки для отображения их в его нижней части (футере).

Все эти ключи являются не обязательными . Если не указать title , то заголовок будет иметь название «Новое окно» . Если не установить значению ключу content , то модальное окно в этом случае создатся с пустым содержимым.

Ключ footerButtons в отличие от title и content принимает в качестве значения массив объектов . Каждый объект в этом массиве представляет собой кнопку . Она задаётся с помощью ключей text , class , handler . С помощью них вы можете установить кнопке (элементу ) текст, значение атрибутов class и data-handler . Если ключ footerButtons вообще не указать, то в этом случае модальное окно будет создано без футера.

Пример создания модального окна с настройками по умолчанию:

Этот код создаст модальное окно без футера, с пустым содержимым и заголовком «Новое окно».

Но функция $modal не только создаёт модальное окно в DOM, но также предоставляет методы для управления им.

Для этого нужно создать переменную и присвоить ей результат выполнения функции $modal .

В эту созданную переменную будет помещён объект (а точнее ссылка на него), имеющий следующие методы:

  • show – для отображения модального окна;
  • hide – для скрытия модального окна;
  • destroy – для удаления модального окна из DOM и связанных с ним обработчиков событий;
  • setContent – для установки контента;
  • setTitle – для установки заголовка.

Эти методы предназначены для взаимодействия с созданным окном. Они позволяют его открыть, закрыть, изменить ему контент и др.

Рассмотрим, как работать с этими методами на примерах.

Например, метод show используется когда вам необходимо показать (открыть) модальное окно:

Метод hide применяется для его скрытия:

Методы setContent и setTitle предназначены соответственно для изменения контента и заголовка модального окна после его создания.

В возвращаемом объекте также есть метод destroy . Его необходимо использовать только когда вам необходимо полностью удалить модальное окно из DOM, а также связанные с ним события:

Данную операцию имеет смысл использовать только в том случае, если созданное модальное окно вам больше не нужно на странице.

Примеры использования скрипта для создания модальных окон

1. Пример кода, выполняющий открытие модального окна при нажатии на определённую кнопку.

2. Пример кода, позволяющий открыть одно и тоже модальное окно посредством клика на разные элементы (определяется элемент, который может открыть это окно, с помощью наличия у него атрибута data-toggle="modal" ):

3. Пример, в котором заголовок и содержимое модального окна определяется посредством значений data-атрибутов элемента, с помощью которого оно вызывается:

4. В этом примере показано как можно в обработчике события «click» для кнопки, расположенной в футере модального окна, получить элемент, посредством которого оно было открыто:

5. Пример, в котором создано 2 разных модальных окна. Первое модальное окно открывается при нажатии на одни элементы, а второе – при клике на другие:

6. Пример всплывающего окна, данные в которое загружаются с использованием AJAX:

Пример содержимого файла «json-1»:

7. Этот пример содержит код для обработки различных событий, связанных с модальном окном и кнопками, расположенными в нём:

Описание скрипта модального окна

В этом разделе приведена информация для тех, кто хочет более подробно разобраться с тем, как работает это модальное окно.

Её JavaScript код представлен посредством функции $modal :

В качестве результата эта функция возвращает объект, состоящий из 5 методов. Они позволяют нам выполнять различные действия над созданным модальным окном. Назначение каждого метода, а также различные примеры как их использовать мы уже подробно рассмотрели выше. Здесь мы более подробно разберём внутренние переменные и функции $modal .

В $modal имеются следующие переменные _elemModal , _eventShowModal , _eventHideModal , _hiding , _destroyed , _animationSpeed и функции _createModal , _showModal , _hideModal , _handlerCloseModal .

Функция _createModal предназначена для формирования HTML-кода модального окна (DOM структуры) и добавления её на страницу. В качестве результата она возвращает ссылку на базовый элемент этого модального окна. Т.к. нам эта ссылка нужна в других частях $modal , то сохраним её в переменную _elemModal :

Переменные _eventShowModal и _eventHideModal применяются для хранения созданных нами кастомных событий «show.modal» и «hide.modal». Событие «show.modal» мы будем вызывать при открытии модального окна, а «hide.modal» – при закрытии. Эти события будем генерировать для объекта document . Используя их, вы можете очень просто добавить свою логику при открытии и закрытии модального окна:

Переменные _hiding и _destroyed используются для хранения состояний. Первая применяется для индикации процесса скрытия модального окна. Она имеет значение true во время скрытия окна, в остальных моментах - false . Вторая переменная хранит true или false , в зависимости от того, удалены ли DOM элементы модального окна со страницы и связанные с ним события или нет.

Переменная _animationSpeed используется для указания времени длительности процесса скрытия модального окна (в миллисекундах).

Функция _showModal предназначена для включения отображения модального окна на странице, а _hideModal – для его скрытия.

Функция _handlerCloseModal используется в качестве обработчика события «click» для документа и выполняет скрытие модального окна при нажатии на кнопку его закрытия или вне его.

Создание модальных окон Bootstrap на JavaScript

Материалы, содержащие базовые моменты по компоненту Bootstrap Modal, доступны по этому адресу.

Модальное окно (HTML-код) не всегда удобно непосредственно размещать на страницах сайта. Т.к. это не только увеличивает размер страницы, но и предусматривает (в большинстве случаев) написания сценария JavaScript по управлению этим окном.

Но используя нижеприведённое решение, вы не только избавитесь от встраивания HTML-кода модального окна на веб-страницу, но и получите методы для простого управления им.

Скрипт JavaScript для управления компонентом Modal

Нижеприведённый сценарий JavaScript не представляет собой ничего сложного – это обычная функция-конструктор. Её назначение создание и управление модальными окнами Bootstrap.

Чтобы не "засорять" глобальное пространство, создание объектов производится в рамках объекта ModalApp .

Для более удобного подключения данного функционала можете воспользоваться следующими файлами:

    - не сжатая версия скрипта для динамического создания модальных окон Bootstrap 3; - сжатая (минимизированная) версия скрипта control-modal.js размером 1,49 КБ. и control-modal-b4.min.js - для Bootstrap 4.

Принцип работы с control-modal.js

1. Вставить или подключить этот скрипт к странице. Это необходимо сделать после подключения библиотеки jQuery и js-плагина Bootstrap.

2. Создать объект "Модальное окно" (ModalProcess).

При создании объекта вы можете передать ему не только параметр id , но и другие параметры:

  • title – заголовок модального окна;
  • body – содержимое модального окна;
  • footer – футер модального окна;
  • selector – добавить элементы (селектор), с помощью которых это модальное окно будет открываться.

Пример, как можно создать объект ModalProcess с id , заголовком, телом и селектором:

Если не указывать параметры, то он создаст модальное окно с параметрами по умолчанию (в качестве id , будет равно modal ).

3. После создания объекта, его необходимо "инициализировать". Это действие, в данном случае, просто добавляет модальное окно на страницу (после открывающего тега body ).

Функции для работы с модальным окном

Для работы с модальным окном Bootstrap данный скрипт предоставляет следующие методы:

  • changeTitle – изменить заголовок;
  • changeBody – изменить содержимое тела;
  • changeFooter – изменить футер;
  • showModal – вызвать (отобразить) модальное окно;
  • hideModal – скрыть модальное окно;
  • updateModal – откорректировать положение компонента Modal.

Примеры использования control-modal.js

Рассмотрим различные примеры, в которых разберём как с помощью control-modal.js можно очень просто создавать и управлять модальными окнами Bootstrap.

Использование модальных окон Bootstrap для отображения AJAX контента

1. Создадим 2 простых php-файла ajax.php и other-ajax.php . Эти файлы будут просто возвращать некоторый контент.

Содержимое файла ajax.php :

Содержимое файла other-ajax.php :

2. HTML документ, содержащий 2 кнопки и JavaScript код:

При этом одно и то же модальное окно используется для отображения разного AJAX контента.

Использование окна для отображения контента data-атрибута

Пример на Bootstrap 4, в котором модальное окно используется для отображения data-атрибута ссылки.

Демо этого же примера, но на Bootstrap 3:

Как из одного окна открыть другое модальное окно

Пример на Bootstrap 4, в котором рассмотрим, как можно очень просто (с помощью control-modal.js ) организовать открытие одного модального окна из другого:

Этот же пример, но с 2 модальными окнами и на Bootstrap 3:

Как использовать одно модальное окно для отображения видео и изображений

В этом примере рассмотрим, как можно использовать одно модальное окно для отображения различного контента, такого как видео и изображения.

Отображение в модальном окне Bootstrap видео с Youtube Отображение в модальном окне Bootstrap изображения

На Bootstrap 3 этот пример (с использованием control-modal.js) доступен посредством следующей ссылки:

Читайте также: