5
0

More than 3 years have passed since last update.

Bootstrap : モーダルを連続で開けない

Posted at

現象

Bootstrap を使って複数のモーダルを連続で開いたときに
2つ目以降のモーダルがスクロールできなくなりました。

NGコード(全文)
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
    integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
    crossorigin="anonymous"></script>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col">
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#firstModal">
          Open Modal!
        </button>
      </div>
    </div>
  </div>
  <!-- 最初のモーダル -->
  <div class="modal fade" id="firstModal">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header"><h2>1st Modal</h2></div>
        <div class="modal-body"><div style="height:1000px">Please Scroll!</div></div>
        <div class="modal-footer">
          <!-- POINT! -->
          <button type="button" class="btn btn-primary" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#secondModal">
              Next
          </button>
        </div>
      </div>
    </div>
  </div>
  <!-- 次のモーダル -->
  <div class="modal fade" id="secondModal">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-header">
          <h2>2nd Modal</h2>
        </div>
        <div class="modal-body">
          <div style="height:1000px">Please Scroll!</div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-primary" data-bs-dismiss="modal">
            Close
          </button>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

原因

上述の NG コードのPOINTの部分では
最初のモーダル内のボタンをクリックすることで
次のモーダルを開くようにしています。

NGコード(POINT部分)
<div class="modal-footer">
  <!-- POINT! -->
  <button type="button" class="btn btn-primary" data-bs-dismiss="modal" data-bs-toggle="modal" data-bs-target="#secondModal">
    Next
  </button>
</div>

Bootstrap ではモーダルを表示する際
body タグにclass="modal-open" を付加するようです。
これによりモーダルの背面のコンテンツをスクロールの対象外としています。

NG コードでは次のモーダルを開いた際
最初のモーダルのクローズにより body タグからclass="modal-open"が削除されてしまいます。
そのため次のモーダルがスクロールされなくなってしまいます。

解決方法

NG コードのあたりを以下のように書き換えてあげると
次のモーダルがスクロールできようになりました。

OKコード
<div class="modal-footer">
  <!-- POINT! -->
  <button type="button" id="nextBtn" class="btn btn-primary">Next</button>
  <script>
    $("#nextBtn").click(function(){ // 処理1
      $("#firstModal").modal("hide");
    });
    $("#firstModal").on("hidden.bs.modal", function(){ // 処理2
      $("#secondModal").modal("show");
    });
  </script>
</div>

NG コードでは以下の 2 つの処理を
最初のモーダル内の button タグに記述しました。

  1. 自分を閉じる(data-bs-dismiss="modal"
  2. 次のモーダルを開く(data-bs-toggle="modal" data-bs-target="#secondModal"

OK コードではこれらの処理を
以下のように JavaScript (今回は jQuery を利用)で制御するようにしました。

  1. 最初のモーダルのボタンがクリックされたら自分を閉じる処理を実行(OK コードの処理1)。
  2. Bootstrap ではモーダルを閉じる際に hidden.bs.modal イベントが発火されるので
    これを拾えたタイミングで次のモーダルを開く(OK コードの処理2)。

こうすることで、
最初のモーダルを開き終わった後でも body タグに class="modal-open" が付与された状態になり、
次のモーダルをスクロールできるようになりました。

参考

Bootstrap の Modal のページ: https://getbootstrap.jp/docs/5.0/components/modal/

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0