Урок, рассматривающий назначение компонента Modal, который используется для создания диалоговых окон на странице.

Bootstrap 3 Bootstrap 4

Назначение и применение компонента Modal

Компонент Modal предназначен для отображения на веб-странице некоторого контента посредством модального окна. В Bootstrap 3 и 4 модальное окно (modal) представляет собой контейнер, который визуально отображается над остальным содержимым страницы.

Bootstrap - Компонент Modal (Модальное окно)
Bootstrap - Компонент Modal

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

Демо работы компонента Modal

Особенности компонента Modal

При использование компонента Modal необходимо учитывать следующие его особенности:

  • Открытие нескольких модальных окон не поддерживается. Это означает то, что авторам, которым требуется данная возможность, необходимо будет её осуществлять самостоятельно посредством написания дополнительного кода.
  • Требование к размещению разметки (HTML-кода) модального окна. HTML-код модального окна желательно располагать в самом верху документа, т.е. после открывающего тега body. Это необходимо выполнить для того, чтобы избежать влияния других компонентов на внешний вид и функциональность модального окна.
  • Предостережения, связанные с использованием компонента Modal на мобильных устройствах. Есть некоторые предостережения, касающиеся использования компонента modal на мобильных устройствах. Первое ограничение связано с тем, что когда Вы прокручиваете вверх или вниз модальное окно в некоторых браузерах на iOS или Android вместе с ним прокручивается и остальное содержимое страницы (содержимое элемента body). Второе ограничение касается ошибки, возникающей при рендеринге положения элементов input в модальном окне в момент вызова виртуальной клавиатуры на устройствах iOS. Для решения этой проблемы обычно используют переключение элементов в position:absolute или вызывают таймер для того чтобы скорректировать позиционирование этих элементов вручную. Более подробно с ограничениями, связанными с применением компонента Modal на мобильных устройствах, можно познакомиться в официальной документации.
Модальному окну Bootstrap Вы не можете установить фокус элементу посредством добавления к нему HTML-атрибута autofocus, это добавит к нему только семантическую ценность.

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

$('#myModal').on('shown.bs.modal', function () {
  //#myInput - id элемента, которому необходимо установить фокус
  $('#myInput').focus();
})

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

Создание и управление модальным окном в Twitter Bootstrap 3 и 4 осуществляется с помощью классов CSS, атрибутов data- и методов JavaScript.

Начинается создание модального окна с его разметки.

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

  • каркас - 3 блока div, имеющие классы .modal, .modal-dialog и .modal-content.
  • header (заголовок) - блок div, имеющий класс .modal-header.
  • body (основное содержимое) - блок div с классом .modal-body.
  • footer (футер) - блок div с классом .modal-footer.
Bootstrap - Структура модального окна
Bootstrap - Структура модального окна

Из всех кирпичиков модального окна обязательными являются только каркас и блок div с классом .modal-body.

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

В качестве примера рассмотрим создание модального окна, имеющего заголовок (header), основное содержимое (body) и футер (footer). Открываться данное модальное окно будет после завершения загрузки страницы.

<!-- HTML-код модального окна -->
<div id="myModalBox" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <!-- Заголовок модального окна -->
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
        <h4 class="modal-title">Заголовок модального окна</h4>
      </div>
      <!-- Основное содержимое модального окна -->
      <div class="modal-body">
        Содержимое модального окна...
      </div>
      <!-- Футер модального окна -->
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Сохранить изменения</button>
      </div>
    </div>
  </div>
</div>

<!-- Скрипт, вызывающий модальное окно после загрузки страницы -->
<script>
  $(document).ready(function() {
    $("#myModalBox").modal('show');
  });
</script>

Активирование модального окна с помощью атрибутов data

В Bootstrap 3 и 4 вызов модального окна можно привязать к кнопке или ссылке вообще без написания кода на языке JavaScript. Осуществляется это с помощью атрибутов data-toggle и data-target. Первый атрибут должен содержать значение modal (data-toggle="modal"), которое будет говорить о том, что содержимое, которое будет вызвать этот элемент, является модальным окном. Второй параметр указывает на элемент (data-target="#myModal" или href="#myModal"), а точнее содержит селектор (идентификатор), с помощью которого выбирается контейнер div, который содержит HTML код модального окна.

<!-- Кнопка, вызывающее модальное окно -->
<a href="#myModal" class="btn btn-primary" data-toggle="modal">Открыть модальное окно</a>

<!-- HTML-код модального окна-->
<div id="myModal" class="modal fade">
  <!--...-->
</div>

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

Вызвать модальное окно можно с помощью кода на языке JavaScript. Для этого в скрипте вызовите метод .modal() с указанием идентификатора (#id) или класса (.class) элемента-контейнера, содержащего HTML-код модального окна.

<!-- Кнопка, открывающая модальное окно -->
<a href="#" class="btn btn-primary">Открыть модальное окно</a>

<!-- HTML-код модального окна-->
<div id="myModal" class="modal fade">
  <!--...-->
</div>

<!-- Скрипт, привязывающий событие click, открывающее модальное окно, к элементам, имеющим класс .btn -->
<script>
$(document).ready(function(){
  //при нажатию на любую кнопку, имеющую класс .btn
  $(".btn").click(function() {
    //открыть модальное окно с id="myModal"
    $("#myModal").modal('show');
  });
});
</script>

Добавление семантики к модальному окну с помощью атрибутов ARIA

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

Атрибуты role="dialog" и aria-labelledby="..." добавьте к элементу модального окна, имеющему класс .modal, и атрибут role="document" к элементу, имеющему класс .modal-dialog.

Кроме этого, Вы также можете добавить описание модальному окну посредством атрибута aria-describedby, который необходимо указать элементу, имеющему класс .modal.

Т.к. по умолчанию модальное окно не отображается, то чтобы это отобразить с помощью стандарта WAI-ARIA добавьте атрибут aria-hidden="true" к элементу, имеющему класс .modal.

Описание ролей и свойств ARIA:

  • role="document" - элемент, содержит связанную информацию, которая может выступать как контент документа.
  • role="dialog" - элемент, выступающий в роли диалога (окно, которое предназначено для прерывания текущей работы приложения с целью запроса у пользователя некоторой информацию или требующей от него ответа).
  • aria-labelledby="..." - предназначен для идентификации элемента (или элементов), который содержат краткое название текущего элемента.
  • aria-describedby="..." - предназначен для идентификации элемента (или элементов), который содержит подробное описание текущего объекта.
  • aria-hidden="true" - указывает, что элемент и все его потомки не видимы пользователю.
  • aria-label="..." – содержит описание текущего элемента.
<!-- Кнопка, открывающее модальное окно -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
  Открыть модальное окно
</button>

<!-- Модальное окно -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Закрыть">
          <span aria-hidden="true">×</span>
        </button>
        <h4 class="modal-title" id="myModalLabel">Заголовок модального окна</h4>
      </div>
      <div class="modal-body">
        Содержимое модального окна...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Сохранить изменения</button>
      </div>
    </div>
  </div>
</div>  

Как убрать анимацию при открытии модального окна

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

<div class="modal" tabindex="-1" role="dialog" aria-labelledby="" aria-hidden="true">
  ...
</div>

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

Платформа Bootstrap 3 и 4 позволяет настраивать размер модального окна. Для этого в этой платформе имеются 2 дополнительных класса: .modal-lg (увеличивает ширину модального окна) и .modal-sm (уменьшает ширину модального окна).

Чтобы изменить размер модального окна один из этих классов необходимо дополнительно поместить рядом с классом .modal-dialog.

<!-- Кнопка, открывающая широкое модальное окно -->
<button class="btn btn-primary" data-toggle="modal" data-target="#largeModal">Открыть ширикое модальное окно </button>
<!-- Широкое модальное окно -->
<div id="largeModal" class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <!--...-->
    </div>
  </div>
</div>
     
<!-- Кнопка, открывающая узкое модальное окно -->
<button class="btn btn-primary" data-toggle="modal" data-target="#smallModal">Открыть узкое модальное окно </button>
<!-- Узкое модальное окно -->
<div id="smallModal" class="modal fade" tabindex="-1" role="dialog">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      <!--...-->
    </div>
  </div>
</div>

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

Для того чтобы использовать систему сеток платформы Twitter Bootstrap 3 или 4 внутри модального окна, достаточно разместить в элементе, имеющего класс .modal-body блок div с классом .container-fluid. После этого можно переходить к созданию необходимой разметки, используя классы системы сеток внутри этого контейнера по обычным правилам.

<!-- Модальное окно, основное содержимое которого организовано с использованием системы сеток Bootstrap 3 или 4 -->
<div id="gridSystemModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Закрыть"><span aria-hidden="true">×</span></button>
        <h4 class="modal-title" id="gridModalLabel">Заголовок модального окна</h4>
      </div>
      <div class="modal-body">
        <!-- основное содержимое (тело) модального окна -->
        <div class="container-fluid">
          <!-- Контейнер, в котором можно создавать классы системы сеток -->
          <div class="row">
            <div class="col-md-6">...</div>
            <div class="col-md-6">...</div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
      </div>
    </div>
  </div>
</div>

<!-- Кнопка, открывающее модальное окно -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#gridSystemModal">
  Открыть модальное окно
</button>

Модальное окно, имеющее динамическую высоту

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

$('#myModal').modal('handleUpdate');

Параметры модального окна

В Bootstrap есть определённые настройки, с помощью которых можно настроить модальное окно. Передача параметров модальному окну осуществляется через атрибуты data или метод .modal().

Имя Тип Описание
backdrop boolean или string 'static' Значение по умолчанию: true. Если установить значение параметра backdrop равное true, то происходит наложение темного фона над всем содержимым веб-страницы, поверх которого отображается модальное окно. Данный эффект используется по умолчанию, для его отмены установите значение backdrop равное false. У данного параметра backdrop есть дополнительное значение 'static', которое запрещает закрывать модальное окно при нажатии за его пределами. Данный параметр также можно установить с помощью data атрибута data-backdrop, например: data-backdrop="static".
keyboard boolean Значение по умолчанию: true. Закрывает модальное окно при нажатии на клавиатуре клавиши Esc. Данный параметр также можно установить с помощью data атрибута data-keyboard.
show boolean Значение по умолчанию: true. Отображает модальное окно сразу после его инициализации. Данный параметр также можно установить с помощью data атрибута data-show.

Метод JavaScript modal() для активации и управления модальным окном

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

Имя Описание
.modal(параметры) Активирует контент, указанный с помощью идентификатора или класса как модальное окно. Принимает в качестве параметров следующие значения: backdrop, keyboard, show. Например:
$('#myModal').modal({ 
  backdrop: 'static',
  keyboard: false 
});
.modal('toggle') Вручную переключает модальное окно, т.е. если модально окно открыто, то скрывает его. А если он скрыто, то отображает его. Например:
$('#myModal').modal('toggle');
.modal('show') Вручную открывает модального окно. Например:
$('#myMmodal').modal('show');
.modal('hide') Вручную скрывает модальное окно. Например:
$('#myMmodal').modal('hide');

Например, активируем модальное окно для элемента, имеющего идентификатор #launch-modal:

<script type="text/javascript">
$(document).ready(function(){
  //подпишемся на событие click элемента, имеющего id="#launch-modal"
  $('#launch-modal').click(function() {
    //активируем контент, имеющий id="myModal", как модальное окно 
    $('#myModal').modal({
      //установим модальному окну следующие параметры:
      backdrop: 'static',
      keyboard: true
    });
  }); 
});
</script>

<!-- HTML код кнопки (для отображения модального окна) -->
<input id="launch-modal" type="button" class="btn btn-primary" value="открыть модальное окно">

<!-- HTML-код модального окна-->
<div id="myModal" class="modal fade">
  <!--...-->
</div>

Например, напишем скрипт, который будет открывать модальное окно каждые 5 минут после загрузки страницы:

<script>
  // после полной загрузки страницы
  $(window).load(function() {
    // вызываем метод setInterval, который будет вызывать модальное окно каждые 5 минут, если оно не открыто
    setInterval(function() {
      // Если окно не открыто (т.е. не имеет класс in)
      if (!$("#myModal").hasClass("in")) {
        // то открыть модальное окно 
        $("#myModal").modal('show');
      }
    }, 300000);
  });
</script>

<!-- Модальное окно-->
<div id="myModal" class="modal fade">
  <!--...-->
</div>

Например, создать модальное окно, которое в зависимости от нажатой кнопки имеет то или иное содержимое.

<!-- Кнопки, открывающие модальное окно myModal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" data-content="Содержимое 1...">Открыть модальное окно с содержимым 1</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" data-content="Содержимое 2...">Открыть модальное окно с содержимым 2</button>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" data-content="Содержимое 1...">Открыть модальное окно с содержимым 3</button>

<!-- Модальное окно myModal -->
<div class="modal fade" id="myModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span>×</span></button>
        <h4 class="modal-title">Заголовок модального окна</h4>
      </div>
      <div class="modal-body">
        <p id="content"></p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
      </div>
    </div>
  </div>
</div>

<script>
// при открытии модального окна
$('#myModal').on('show.bs.modal', function (event) {
  // получить кнопку, которая его открыло
  var button = $(event.relatedTarget) 
  // извлечь информацию из атрибута data-content
  var content = button.data('content') 
  // вывести эту информацию в элемент, имеющий id="content"
  $(this).find('#content').text(content); 
})
</script>

События, связанные с модальным окном

Изменение состояния модального окна (открытие, закрытие) Вы можете получить с помощью следующих событий:

Имя Описание
show.bs.modal Событие происходит, когда вызывается метод show(), предназначенный для открытия модального окна. Если модальное окно вызывается с помощью клика (click), то элемент, который вызвал открытие модального окна, будет доступен как свойство relatedTarget события.
Например:
$('#myMmodal').on('show.bs.modal', function() {
  // сделать что-нибудь...
})
shown.bs.modal Событие происходит, когда модальное окно становится видимым для пользователя, т.е. когда оно будет полностью отрисовано с помощью стилей CSS. Если модальное окно вызывается с помощью клика (click), то элемент, который вызвал открытие модального окна будет доступен как свойство relatedTarget события.
Например:
$('#myMmodal').on('shown.bs.modal', function() {
  // сделать что-нибудь...
})
hide.bs.modal Событие происходит, когда вызывается метод hide(), который предназначен для скрытия модального окна.
Например:
$('#myMmodal').on('hide.bs.modal', function() {
  // сделать что-нибудь...
})
hidden.bs.modal Событие происходит, когда модальное окно становится полностью невидимым для пользователя, т.е. когда будут отработаны полностью все CSS-свойства, выполняющие этот процесс.
Например:
$('#myMmodal').on('hidden.bs.modal', function() {
  // сделать что-нибудь...
})

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

<script>
$(document).ready(function(){
  //при нажатию на элемент, имеющий класс .open-modal, открыть модальное окно 
  $('.open-modal').click(function(){
    $('#myModal').modal('show');
  });
  //отобразить сообщение, когда модальное окно будет полностью скрыто от пользователя
  $("#myModal").on('hidden.bs.modal', function(){
    alert("Модальное окно было успешно закрыто.");
  });
});
</script>

<!-- Кнопка, открывающая модальное окно -->
<input type="button" class="btn btn-primary open-modal" value="Открыть модальное окно">

<!-- HTML-код модального окна-->
<div id="myModal" class="modal fade">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Заголовок модального окна</h4>
      </div>
      <div class="modal-body">
        <p>Содержимое модального окна...</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
      </div>
    </div>
  </div>
</div>

Результат вышепредставленного примера представим в виде следующих изображений:

HTML-страница, на которой расположена кнопка, открывающее модальное окно Bootstrap
Кнопка, открывающее модальное окно Bootstrap
HTML-страница, на которой открыто модальное окно Bootstrap
Открытое модальное окно Bootstrap
HTML-страница, на которой отображён результат отработки события hidden.bs.modal, которое происходит после полного скрытия модального окна
Результат отработки события hidden.bs.modal