現象
Bootstrap を使って複数のモーダルを連続で開いたときに
2つ目以降のモーダルがスクロールできなくなりました。
<!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
の部分では
最初のモーダル内のボタンをクリックすることで
次のモーダルを開くようにしています。
<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 コードのあたりを以下のように書き換えてあげると
次のモーダルがスクロールできようになりました。
<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 タグに記述しました。
- 自分を閉じる(
data-bs-dismiss="modal"
) - 次のモーダルを開く(
data-bs-toggle="modal" data-bs-target="#secondModal"
)
OK コードではこれらの処理を
以下のように JavaScript (今回は jQuery を利用)で制御するようにしました。
- 最初のモーダルのボタンがクリックされたら自分を閉じる処理を実行(OK コードの処理1)。
- Bootstrap ではモーダルを閉じる際に
hidden.bs.modal
イベントが発火されるので
これを拾えたタイミングで次のモーダルを開く(OK コードの処理2)。
こうすることで、
最初のモーダルを開き終わった後でも body タグに class="modal-open"
が付与された状態になり、
次のモーダルをスクロールできるようになりました。
参考
Bootstrap の Modal のページ: https://getbootstrap.jp/docs/5.0/components/modal/