Bootstrap V5 вручную вызывает модальный myModal.show() не работает (ванильный javascript)

Каков правильный способ вручную вызвать модальное окно в bootstrap 5?

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

мой модальный

<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
        ... 
        ... 
        ... 
    </div>
  </div>
</div>

мой сценарий

var myModal = document.getElementById('myModal');
document.onreadystatechange = function() {
   
    myModal.show();
}

но получил эту ошибку в журнале консоли:

 myModal.show is not a function
    at HTMLDocument.document.onreadystatechange

9 ответов

Решение

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

Как использовать через Vanilla JavaScript

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

var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)

источник

Быстрый пример:

var myModal = new bootstrap.Modal(document.getElementById("exampleModal"), {});
document.onreadystatechange = function () {
  myModal.show();
};
<!DOCTYPE html>
<html lang="en">
  <head>

    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />


    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css"
      integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I"
      crossorigin="anonymous"
    />
    <title>Hello, world!</title>
  </head>
  <body>

    <div
      class="modal fade"
      id="exampleModal"
      tabindex="-1"
      role="dialog"
      aria-labelledby="exampleModalLabel"
      aria-hidden="true"
    >
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
            <button
              type="button"
              class="close"
              data-dismiss="modal"
              aria-label="Close"
            >
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            ...
          </div>
          <div class="modal-footer">
            <button
              type="button"
              class="btn btn-secondary"
              data-dismiss="modal"
            >
              Close
            </button>
            <button type="button" class="btn btn-primary">Save changes</button>
          </div>
        </div>
      </div>
    </div>

    <!-- JavaScript and dependencies -->
    <script
      src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
      integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"
      integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/"
      crossorigin="anonymous"
    ></script>

    <script src="./app.js"></script>
  </body>
</html>

Что касается вашего кода, вы не следовали правильному пути для отображения / переключения модального окна в Vanilla JavaScript. Почему ты ожидалmyModal.show() случиться пока myModal это просто элемент DOM?

  1. Создайте новый модальный экземпляр, а затем вызовите метод show (см. Пункты использования)

    var myModal = новый bootstrap.Modal(document.getElementById('exampleModal')) myModal.show()

ссылка: https://v5.getbootstrap.com/docs/5.0/components/modal/

примечание: Bootstrap v5 больше не использует jquery, вместо этого он использует javascript. В bootstrap v5 внесено множество изменений, если вы работаете в компании и хотите использовать Bootstrap v5, пожалуйста, внесите все изменения.

[Bootstrap 5+, ванильный js, bootstrapимпортируется как глобальный ]

      let modal = bootstrap.Modal.getOrCreateInstance(document.getElementById('myModal')) // Returns a Bootstrap modal instance
// Show or hide:
modal.show();
modal.hide();

Подробнее здесь: https://getbootstrap.com/docs/5.0/components/modal/#getorcreateinstance

Основываясь на коде javascript, предоставленном OP, я думаю, что фактическая цель здесь - связаться с компонентом с помощью элемента DOM . Я также искал способ сделать это, поэтому хотел поделиться тем, что нашел (или не нашел).

v4- Это было возможно и обычно использовалось с более ранними версиями. В v4 мы могли бы легко использовать его с jQuery, хотя компонент инициализируется атрибутами данных, а не напрямую из js.

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

v5.0.0-beta2 В новой версии очень многообещающий пример API предоставляется в документации для другого типа компонента. Однако в настоящее время он, похоже, не работает. (https://getbootstrap.com/docs/5.0/getting-started/javascript/#asynchronous-functions-and-transitions)

      var myModal = document.getElementById('myModal')
var modal = bootstrap.Modal.getInstance(myModal) 
console.log(modal) // null

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

Последнее замечание: все еще можно включить jQuery до скрипта v5 и добиться этого. (Https://codepen.io/cadday/pen/Jjbvxvm )

      window.onload = function() {
  console.log(jQuery('#myModal').modal('show'));
}

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

Я также добавил возможность временно удалить эффект затухания, если вы хотите, чтобы он открывался сразу после загрузки страницы. Для этого просто необходимо использовать data-auto-open = "Instant" вместо пустого атрибута data-auto-open . После того, как он закроется один раз, и вы захотите снова открыть его вручную, снова будет эффект затухания.

Рабочее решение в TypeScript для Bootstrap 5.0.0-Beta3 будет таким:

      // @ts-ignore
import { Modal } from 'bootstrap';

window.addEventListener('DOMContentLoaded', (event) => {
    const selector = '[data-auto-open]';
    const modalElement: HTMLElement | null = document.querySelector(selector);

    if (!modalElement) {
        return;
    }

    const mode = modalElement.dataset.autoOpen;
    const fade = modalElement.classList.contains('fade');

    if (fade && mode === 'instant') {
        modalElement.classList.remove('fade');
    }

    const modal = new Modal(modalElement, {});

    if (fade && mode === 'instant') {
        // There's currently a bug in the backdrop when the fade class 
        // will be added directly after the modal was opened to have the
        // close animation
        // modalElement.addEventListener('shown.bs.modal', function (event) {
        modalElement.addEventListener('hidden.bs.modal', function (event) {
            modalElement.classList.add('fade');
        }, {once : true});
    }

    modal.show();
}, {once : true});

HTML будет стандартным:

      <!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
    Demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" data-auto-open>
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">
                    Example Modal title
                </h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
                eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-cancel" data-bs-dismiss="modal">
                    Close
                </button>
            </div>
        </div>
    </div>
</div>

[Bootstrap 5]

Плагины могут быть включены индивидуально (с использованием отдельных js / dist / *. Js в Bootstrap) или все сразу с использованием bootstrap.js или минифицированного bootstrap.min.js (не включайте оба).

Если вы используете пакет (Webpack, Rollup…), вы можете использовать файлы /js/dist/*.js, готовые для UMD.

Например, если вы хотите импортировать только модальный плагин из Bootstrap 5, вы можете сделать это:

Добавьте оператор импорта вверху вашего js файла

      import Modal from 'bootstrap/js/dist/modal';

А затем покажите модальное окно, например, при нажатии на элемент кнопки:

      const myButton = document.getElementById('my-button-id');
const myModal  = document.getElementById('my-modal-id');

const modal = new Modal(myModal); // Instantiates your modal

myButton.addEventListener('click', () => {
    modal.show(); // shows your modal
});

Самый быстрый способ сделать это

      new bootstrap.Modal($('#MyModal')).show();

Простой способ открыть / показать модальное диалоговое окно в Bootstrap 5 - создать ссылку в вашем HTML-коде (она может быть невидимой), а затем создать / запустить событие щелчка по ссылке.

Вот пример:

Ссылка для открытия модального диалога:

      <a id=test data-bs-toggle="modal" href="#MODAL-ID"></a>

Код JavaScript для запуска события щелчка по этой ссылке:

      triggerEvent(test,'click');

function triggerEvent(el,evName)
    {el.dispatchEvent(new CustomEvent(evName,{}));}

Другие вопросы по тегам