Перейти к основному содержанию Перейти к навигации по документам
Check
Cмотреть на GitHub

Модальное окно

Используйте модальный JavaScript плагин Bootstrap для добавления диалоговых окнон на ваш сайт для лайтбоксов, уведомлений пользователей или полностью настраиваемого контента.

Как это работает

До того как начать работу с модальными компонентами Bootstrap, ознакомьтесь со следующей информацией, т.к. параметры недавно изменились.

  • Модальные окна сделаны на HTML, CSS и JavaScript. Они располагаются поверх всего документа и блокируют прокрутку тела документа <body>, вместо него прокручивая модальные окна
  • Клик вне модального элемента автоматически закрывает его.
  • Bootstrap позволяет активировать лишь один модальный элемент за раз. Вложенные модальные элементы не поддерживаются, т.к. мы думаем, что они принесли бы неудобства.
  • Модальные элементы имеют position: fixed, что может вызвать иногда их частичную отрисовку. Мы рекомендуем размещать модальные элементы на самом верху страницы, когда возможно, для избегания сбоев и влияния других элементов на корректную работу модальных элементов .modal.
  • Опять же – из-за position: fixed есть некоторые сложности при использовании их на мобильных устройствах. Смотри документацию поддержки в браузерах.
  • Из-за семантики HTML5 атрибут autofocus не работает с модальными элементами Bootstrap. Чтобы добиться такого же эффекта, используйте собственный JavaScript:
const myModal = document.getElementById('myModal')
const myInput = document.getElementById('myInput')

myModal.addEventListener('shown.bs.modal', () => {
  myInput.focus()
})
Эффект анимации этого компонента зависит от медиа-запроса с ограниченным движением prefers-reduced-motion. Смотрите раздел специальных возможностей в нашей документации по редукции анимации.

Далее – демонстрация примеров и инструкции по использованию.

Примеры

Ниже приведен пример статического модального окна (это означает, что его position и display были переопределены). Включены модальный заголовок, модальное тело (требуется для padding) и модальный нижний колонтитул (необязательно). Мы просим вас по возможности включать модальные заголовки с действиями по отклонению или предоставить другое явное действие по отклонению.

<div class="modal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Заголовок модального окна</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        <p>Здесь идет основной текст модального окна</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Сохранить изменения</button>
      </div>
    </div>
  </div>
</div>

«Живое» демо

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

<!-- Кнопка-триггер модального окна -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Запустите демо модального окна
</button>

<!-- Модальное окно -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Заголовок модального окна</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Сохранить изменения</button>
      </div>
    </div>
  </div>
</div>

Статический фон

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

<!-- Кнопка-триггер модального окна -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
  Запустить модальное окно со статическим фоном
</button>

<!-- Модальное окно -->
<div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="staticBackdropLabel">Заголовок модального окна</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Понял</button>
      </div>
    </div>
  </div>
</div>

Прокрутка длинного содержимого

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

Вы также можете создать прокручиваемое модальное окно, которое позволяет прокручивать модальное тело, добавляя .modal-dialog-scrollable к .modal-dialog.

<!-- Прокручиваемое модальное окно -->
<div class="modal-dialog modal-dialog-scrollable">
  ...
</div>

Вертикальное центрирование

Добавьте .modal-dialog-centered к .modal-dialog для вертикального центрирования модального окна.

<!-- Вертикально центрированное модальное окно -->
<div class="modal-dialog modal-dialog-centered">
  ...
</div>

<!-- Вертикально центрированное прокручиваемое модальное окно -->
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
  ...
</div>

Всплывающие подсказки и возникающие подсказки

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

<div class="modal-body">
  <h5>Поповер в модальном окне</h5>
  <p>Эта <a href="#" role="button" class="btn btn-secondary" data-bs-toggle="popover" title="Popover title" data-bs-content="Popover body content is set in this attribute.">кнопка</a> вызывает всплывающее окно при нажатии.</p>
  <hr>
  <h5>Подсказки в модальном окне</h5>
  <p><a href="#" data-bs-toggle="tooltip" title="Tooltip">Эта ссылка</a> и <a href="#" data-bs-toggle="tooltip" title="Tooltip">эта ссылка</a> имеет всплывающие подсказки при наведении.</p>
</div>

Использование сетки

Используйте сеточную систему Bootstrap в модальном окне, вложив .container-fluid в .modal-body. Затем используйте обычные классы системы сетки, как и везде.

<div class="modal-body">
  <div class="container-fluid">
    <div class="row">
      <div class="col-md-4">.col-md-4</div>
      <div class="col-md-4 ms-auto">.col-md-4 .ms-auto</div>
    </div>
    <div class="row">
      <div class="col-md-3 ms-auto">.col-md-3 .ms-auto</div>
      <div class="col-md-2 ms-auto">.col-md-2 .ms-auto</div>
    </div>
    <div class="row">
      <div class="col-md-6 ms-auto">.col-md-6 .ms-auto</div>
    </div>
    <div class="row">
      <div class="col-sm-9">
        Level 1: .col-sm-9
        <div class="row">
          <div class="col-8 col-sm-6">
            Level 2: .col-8 .col-sm-6
          </div>
          <div class="col-4 col-sm-6">
            Level 2: .col-4 .col-sm-6
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Комбинируйте содержимое модальных элементов

Есть много кнопок, которые все запускают один модальный элемент со слегка разным содержимым? Используйте event.relatedTarget и атрибуты data-bs-* для изменения содержимого в зависимости от нажатой кнопки.

Ниже – пример демо с кодом HTML и JavaScript. Для информации по relatedTarget читайте инфо по событиям модальных элементов.

html
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@mdo">Открыть модальное окно для @mdo</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@fat">Открыть модальное окно для @fat</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@getbootstrap">Открыть модальное окно для @getbootstrap</button>

<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Новое сообщение</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="mb-3">
            <label for="recipient-name" class="col-form-label">Получатель:</label>
            <input type="text" class="form-control" id="recipient-name">
          </div>
          <div class="mb-3">
            <label for="message-text" class="col-form-label">Сообщение:</label>
            <textarea class="form-control" id="message-text"></textarea>
          </div>
        </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
        <button type="button" class="btn btn-primary">Отправить сообщение</button>
      </div>
    </div>
  </div>
</div>
const exampleModal = document.getElementById('exampleModal')
exampleModal.addEventListener('show.bs.modal', event => {
  // Кнопка, которая активировала модальное окно
  const button = event.relatedTarget
  // Извлекает информацию из атрибутов data-bs-*
  const recipient = button.getAttribute('data-bs-whatever')
  // При необходимости вы можете инициировать запрос AJAX здесь,
  // а затем выполнить обновление в обратном вызове.
  //
  // Обновляет содержимое модального окна.
  const modalTitle = exampleModal.querySelector('.modal-title')
  const modalBodyInput = exampleModal.querySelector('.modal-body input')

  modalTitle.textContent = `New message to ${recipient}`
  modalBodyInput.value = recipient
})

Переключение между модальными окнами

Переключайтесь между несколькими модальными окнами с умным размещением атрибутов data-bs-target и data-bs-toggle attributes. Например, вы можете переключить модальное окно сброса пароля из уже открытого модального окна входа. Обратите внимание, что несколько модальных окон не могут быть открыты одновременн — этот метод просто переключается между двумя отдельными модальными окнами.

Открыть первое модальное окно
html
<div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalToggleLabel">Модалка 1</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        Покажите второе модальное окно и скройте его с помощью кнопки ниже.
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" data-bs-target="#exampleModalToggle2" data-bs-toggle="modal">Открыть второе модальное окно</button>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="exampleModalToggle2" aria-hidden="true" aria-labelledby="exampleModalToggleLabel2" tabindex="-1">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalToggleLabel2">Модалка 2</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>
      </div>
      <div class="modal-body">
        Скройте это модальное окно и покажите первое с помощью кнопки ниже.
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" data-bs-target="#exampleModalToggle" data-bs-toggle="modal">Вернуться к первому</button>
      </div>
    </div>
  </div>
</div>
<a class="btn btn-primary" data-bs-toggle="modal" href="#exampleModalToggle" role="button">Открыть первое модальное окно</a>

Изменение анимации

Переменная $modal-fade-transform определяет состояние преобразования .modal-dialog перед анимацией постепенного появления, переменная $modal-show-transform определяет преобразование .modal-dialog в конце модального появления анимация.

Если вы хотите, например, анимацию увеличения, вы можете установить $modal-fade-transform: scale(.8).

Анимация при удалении

Для модальных окон, которые просто появляются, а не исчезают при просмотре, удалите класс .fade из Вашей модальной разметки.

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

Динамическая высота

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

Доступность

Не забудьте добавить aria-labelledby="...", ссылаясь на Заголовок модального окна, в .modal. Кроме того, Вы можете дать описание Вашего модального диалога с помощью aria-describedby в .modal. Обратите внимание, что Вам не нужно добавлять role="dialog", поскольку мы уже добавляем его через JavaScript..

Встраивание видео из YouTube

Встраивание видео YouTube в модальные окна требует дополнительного JavaScript не в Bootstrap для автоматической остановки воспроизведения и т.д. См. этот полезный пост о переполнении стека для получения дополнительной информации.

Дополнительные размеры

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

Размер Класс Максимальная ширина модального окна
Маленький .modal-sm 300px
По умолчанию Нет 500px
Большой .modal-lg 800px
Очень большой .modal-xl 1140px

Наш модальный класс по умолчанию без модификатора представляет собой модальное окно «среднего» размера.

<div class="modal-dialog modal-xl">...</div>
<div class="modal-dialog modal-lg">...</div>
<div class="modal-dialog modal-sm">...</div>

Полноэкранная модаль

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

Класс Доступность
.modal-fullscreen Всегда
.modal-fullscreen-sm-down 576px
.modal-fullscreen-md-down 768px
.modal-fullscreen-lg-down 992px
.modal-fullscreen-xl-down 1200px
.modal-fullscreen-xxl-down 1400px
<!-- Полноэкранное модальное окно -->
<div class="modal-dialog modal-fullscreen-sm-down">
  ...
</div>

CSS

Переменные

Добавлено в версии 5.2.0

Как часть развивающегося подхода Bootstrap к переменным CSS, модальные окна теперь используют локальные переменные CSS в .modal и .modal-backdrop для расширенной настройки в реальном времени. Значения переменных CSS задаются через Sass, поэтому настройка Sass по-прежнему поддерживается.

  --#{$prefix}modal-zindex: #{$zindex-modal};
  --#{$prefix}modal-width: #{$modal-md};
  --#{$prefix}modal-padding: #{$modal-inner-padding};
  --#{$prefix}modal-margin: #{$modal-dialog-margin};
  --#{$prefix}modal-color: #{$modal-content-color};
  --#{$prefix}modal-bg: #{$modal-content-bg};
  --#{$prefix}modal-border-color: #{$modal-content-border-color};
  --#{$prefix}modal-border-width: #{$modal-content-border-width};
  --#{$prefix}modal-border-radius: #{$modal-content-border-radius};
  --#{$prefix}modal-box-shadow: #{$modal-content-box-shadow-xs};
  --#{$prefix}modal-inner-border-radius: #{$modal-content-inner-border-radius};
  --#{$prefix}modal-header-padding-x: #{$modal-header-padding-x};
  --#{$prefix}modal-header-padding-y: #{$modal-header-padding-y};
  --#{$prefix}modal-header-padding: #{$modal-header-padding}; // Todo in v6: Split this padding into x and y
  --#{$prefix}modal-header-border-color: #{$modal-header-border-color};
  --#{$prefix}modal-header-border-width: #{$modal-header-border-width};
  --#{$prefix}modal-title-line-height: #{$modal-title-line-height};
  --#{$prefix}modal-footer-gap: #{$modal-footer-margin-between};
  --#{$prefix}modal-footer-bg: #{$modal-footer-bg};
  --#{$prefix}modal-footer-border-color: #{$modal-footer-border-color};
  --#{$prefix}modal-footer-border-width: #{$modal-footer-border-width};
  
  --#{$prefix}backdrop-zindex: #{$zindex-modal-backdrop};
  --#{$prefix}backdrop-bg: #{$modal-backdrop-bg};
  --#{$prefix}backdrop-opacity: #{$modal-backdrop-opacity};
  

Переменные Sass

$modal-inner-padding:               $spacer;

$modal-footer-margin-between:       .5rem;

$modal-dialog-margin:               .5rem;
$modal-dialog-margin-y-sm-up:       1.75rem;

$modal-title-line-height:           $line-height-base;

$modal-content-color:               null;
$modal-content-bg:                  $white;
$modal-content-border-color:        var(--#{$prefix}border-color-translucent);
$modal-content-border-width:        $border-width;
$modal-content-border-radius:       $border-radius-lg;
$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width);
$modal-content-box-shadow-xs:       $box-shadow-sm;
$modal-content-box-shadow-sm-up:    $box-shadow;

$modal-backdrop-bg:                 $black;
$modal-backdrop-opacity:            .5;

$modal-header-border-color:         var(--#{$prefix}border-color);
$modal-header-border-width:         $modal-content-border-width;
$modal-header-padding-y:            $modal-inner-padding;
$modal-header-padding-x:            $modal-inner-padding;
$modal-header-padding:              $modal-header-padding-y $modal-header-padding-x; // Keep this for backwards compatibility

$modal-footer-bg:                   null;
$modal-footer-border-color:         $modal-header-border-color;
$modal-footer-border-width:         $modal-header-border-width;

$modal-sm:                          300px;
$modal-md:                          500px;
$modal-lg:                          800px;
$modal-xl:                          1140px;

$modal-fade-transform:              translate(0, -50px);
$modal-show-transform:              none;
$modal-transition:                  transform .3s ease-out;
$modal-scale-transform:             scale(1.02);

Цикл

Адаптивные полноэкранные модальные окна генерируются с помощью карты $breakpoints и цикла в scss/_modal.scss.

@each $breakpoint in map-keys($grid-breakpoints) {
  $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
  $postfix: if($infix != "", $infix + "-down", "");

  @include media-breakpoint-down($breakpoint) {
    .modal-fullscreen#{$postfix} {
      width: 100vw;
      max-width: none;
      height: 100%;
      margin: 0;

      .modal-content {
        height: 100%;
        border: 0;
        @include border-radius(0);
      }

      .modal-header,
      .modal-footer {
        @include border-radius(0);
      }

      .modal-body {
        overflow-y: auto;
      }
    }
  }
}

Использование

Модальный плагин переключает ваш скрытый контент по запросу с помощью атрибутов данных или JavaScript. Он также переопределяет поведение прокрутки по умолчанию и генерирует .modal-backdrop, чтобы предоставить область клика для отклонения отображаемых модальных окон при щелчке вне модального окна.

Через атрибуты данных

Переключение

Активируйте модальное окно без написания JavaScript. Установите data-bs-toggle="modal" на элемент контроллера, например кнопку, вместе с data-bs-target="#foo" или href="#foo" для нацеливания на конкретное модальное окно для переключения.

<button type="button" data-bs-toggle="modal" data-bs-target="#myModal">Запустить модальное окно</button>

Отклонение

Отклонение может быть достигнуто с помощью атрибута data на кнопке внутри modal, как показано ниже:

<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Закрыть"></button>

или на кнопке за пределами modal с помощью data-bs-target, как показано ниже:

<button type="button" class="btn-close" data-bs-dismiss="modal" data-bs-target="#my-modal" aria-label="Закрыть"></button>
Хотя поддерживаются оба способа отклонения модального окна, имейте в виду, что удаление модального окна извне не соответствует Шаблон диалогового окна (модального) Руководства по авторской работе ARIA. Делайте это на свой страх и риск.

Через JavaScript

Создайте модальное окно с одной строкой JavaScript:

const myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
// or
const myModalAlternative = new bootstrap.Modal('#myModal', options)

Опции

Поскольку параметры можно передавать через атрибуты данных или JavaScript, вы можете добавить имя параметра к data-bs-, как в data-bs-animation="{value}". Обязательно измените тип регистра имени параметра с “camelCase” на “kebab-case” при передаче параметров через атрибуты данных. Например, используйте data-bs-custom-class="beautifier" вместо data-bs-customClass="beautifier".

Начиная с Bootstrap 5.2.1, все компоненты поддерживают экспериментальный зарезервированный атрибут данных data-bs-config, который может содержать простую конфигурацию компонента в виде строки JSON. Когда элемент имеет атрибуты data-bs-config='{"delay":0, "title":123}' и data-bs-title="456", окончательное значение title будет 456, а отдельные атрибуты данных переопределяют значения, указанные в data-bs-config. Кроме того, существующие атрибуты данных могут содержать значения JSON, такие как data-bs-delay='{"show":0,"hide":150}'.

Название Тип По умолчанию Описание
backdrop boolean, 'static' true Включает элемент модального фона. В качестве альтернативы укажите static для фона, который не закрывает модальное окно при нажатии.
focus boolean true Ставит фокус на модальное окно при инициализации.
keyboard boolean true Закрывает модальное окно при нажатии клавиши escape.

Методы

Асинхронные методы и переходы

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

Дополнительную информацию см. в нашей документации по JavaScript.

Варианты прохождения

Активирует Ваш контент как модальное окно. Принимает необязательные параметры object.

const myModal = new bootstrap.Modal('#myModal', {
  keyboard: false
})
Метод Описание
dispose Уничтожает модальное окно элемента. (Удаляет сохраненные данные в элементе DOM)
getInstance Статический метод, позволяющий получить модальный экземпляр, связанный с элементом DOM.
getOrCreateInstance Статический метод, который позволяет вам получить модальный экземпляр, связанный с элементом DOM, или создать новый, если он не был инициализирован.
handleUpdate Вручную отрегулируйте положение модального окна, если высота модального окна изменяется, когда оно открыто (например, в случае появления полосы прокрутки).
hide Вручную скрывает модальное окно. Возврат к вызывающей стороне до того, как модальное окно будет фактически скрыто (т.е. до того, как произойдет событие hidden.bs.modal).
show Вручную открывает модальное окно. Возврат к вызывающей стороне до того, как модальное окно действительно будет показано (т.е. до того, как произойдет событие shown.bs.modal). Кроме того, вы можете передать элемент DOM в качестве аргумента, который может быть получен в модальных событиях (как свойство relatedTarget). (т.е. const modalToggle = document.getElementById('toggleMyModal'); myModal.show(modalToggle)
toggle Вручную переключает модальное окно. Возврат к вызывающей стороне до того, как модальное окно было действительно показано или скрыто (т.е. до того, как произошло событие shown.bs.modal или hidden.bs.modal).

События

Модальный класс Bootstrap предоставляет несколько событий для подключения к модальным функциям. Все модальные события запускаются в самом модальном окне (то есть в <div class="modal">).

Событие Описание
hide.bs.modal Это событие запускается сразу после вызова метода экземпляра hide.
hidden.bs.modal Это событие запускается, когда модальное окно больше не скрыто от пользователя (будет ждать завершения переходов CSS).
hidePrevented.bs.modal Это событие запускается, когда отображается модальное окно, его фон является static и выполняется щелчок за пределами модального окна. Событие также запускается, когда нажата клавиша escape, а для параметра keyboard установлено значение false.
show.bs.modal Это событие срабатывает немедленно при вызове метода экземпляра show. Если это вызвано щелчком, элемент, по которому щелкнули, доступен как свойство relatedTarget.
shown.bs.modal Это событие запускается, когда модальное окно становится видимым для пользователя (будет ждать завершения переходов CSS). Если это вызвано щелчком, элемент, по которому щелкнули, доступен как свойство relatedTarget.
const myModalEl = document.getElementById('myModal')
myModalEl.addEventListener('hidden.bs.modal', event => {
  // сделайте что-нибудь...
})