この記事では、jQueryを使ってモーダルウィンドウをさくっと作成する方法をご紹介します。
結論から書くと、HTMLのダイアログ要素 <dialog> を使えばjQueryもCSSもほぼ書かずに作れます。Escキーでの閉じる操作もフォーカスの制御も最初から備わっています。既存サイトにjQueryが入っている場合は、この記事のjQuery版が使えます。
両方の作り方を載せるので、状況に合うほうを選んでください。
スポンサーリンク
モーダルウィンドウの作成例
この記事で作成するモーダルウィンドウの作成例です。
See the Pen
jQuery-モーダルウィンドウ by りん@エンジニア (@rinblog0408)
on CodePen.
モーダルウィンドウのHTML構造を作成する
モーダルウィンドウを表示するために、HTML内にモーダルのコンテンツを定義します。今回はjQueryを使うので、jQueryのライブラリの読み込みも記述しておきます。
<div id="myModal" class="modal">
<div class="modal-content">
<div>
<p>モーダルのコンテンツをここに追加</p>
</div>
<button id="closeModalBtn">閉じる</button>
</div>
</div>
<button id="openModalBtn">モーダルを開く</button>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
読み込むjQueryのバージョンに注意してください。3.5.0より前のjQueryにはXSSの脆弱性(CVE-2020-11022 / CVE-2020-11023)があります。公開するサイトでは3.5.1以降を読み込んでください。
スポンサーリンク
CSSスタイルの追加
モーダルウィンドウを見栄え良く表示するために、CSSスタイルを追加します。
.modal {
display: none; /* 初期状態では非表示 */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); /* モーダル背景の半透明な黒 */
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
padding: 20px;
}
jQueryを使用してモーダルを表示する
以下のjQueryコードを追加すると、ボタンをクリックしたときにモーダルウィンドウが表示されます。
$(document).ready(function() {
$("#openModalBtn").on("click", function() {
$("#myModal").show(); // モーダルを表示
});
$("#closeModalBtn").on("click", function() {
$("#myModal").hide(); // モーダルを非表示
});
});
開閉だけでは足りない3つのこと
結論:上のコードはモーダルの見た目を作るだけで、モーダルとして必要な挙動が3つ足りていません。
▼足りない挙動
| 不足 | 起きること |
|---|---|
| Escキーで閉じられない | キーボードだけの操作で閉じられない |
| 背景をクリックしても閉じない | 閉じるボタンを探すことになる |
| 背景の要素にフォーカスが移る | Tabキーでモーダルの外へ抜けてしまう |
最初の2つはすぐ足せます。
$(document).ready(function() {
const $modal = $("#myModal");
function openModal() {
$modal.show();
// モーダル内の最初のボタンにフォーカスを移す
$modal.find("button").first().trigger("focus");
}
function closeModal() {
$modal.hide();
// 開いたボタンにフォーカスを戻す
$("#openModalBtn").trigger("focus");
}
$("#openModalBtn").on("click", openModal);
$("#closeModalBtn").on("click", closeModal);
// 背景(オーバーレイ)のクリックで閉じる
$modal.on("click", function(e) {
if (e.target === this) closeModal();
});
// Escキーで閉じる
$(document).on("keydown", function(e) {
if (e.key === "Escape" && $modal.is(":visible")) closeModal();
});
});
e.target === this の判定が要ります。これが無いと、モーダルの中身をクリックしただけでも閉じてしまいます。
3つ目のフォーカスの閉じ込め(フォーカストラップ)を自前で書くのは手間がかかります。そこまで必要なら、次の <dialog> を使うほうが早いです。
スポンサーリンク
dialog要素ならJavaScriptがほぼ要らない
結論:HTMLの <dialog> 要素を使うと、Escキーでの閉じる操作、背景の暗転、フォーカスの制御が最初から付いてきます。
<dialog id="myDialog">
<p>モーダルのコンテンツをここに追加</p>
<form method="dialog">
<button>閉じる</button>
</form>
</dialog>
<button id="openDialogBtn">モーダルを開く</button>
const dialog = document.getElementById("myDialog");
document.getElementById("openDialogBtn").addEventListener("click", () => {
dialog.showModal();
});
JavaScriptはこの3行だけです。
showModal() で開くのがポイントです。show() でも表示できますが、それだと背景が操作できてしまい、モーダルになりません。
showModal():背景を操作できなくする(モーダル)show():背景を操作できる(モードレス)
閉じるボタンは <form method="dialog"> で囲むと、JavaScriptを書かずに閉じられます。
背景(バックドロップ)のスタイルは ::backdrop で指定します。
#myDialog {
border: none;
border-radius: 8px;
padding: 20px;
}
#myDialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
背景クリックで閉じたい場合だけ、数行足します。
dialog.addEventListener("click", (e) => {
if (e.target === dialog) dialog.close();
});
<dialog> の中身は要素の内側に描かれるため、e.target が dialog 自身になるのは背景部分をクリックしたときだけです。
どちらの作り方を選ぶか
結論:新しく作るなら <dialog>、既存サイトに足すならjQuery版です。
▼2つの作り方の比較
| dialog要素 | CSS + jQuery | |
|---|---|---|
| JavaScript | 3行 | 開閉+Esc+背景クリック |
| Escキーで閉じる | 最初から対応 | 自分で書く |
| 背景の暗転 | ::backdrop |
自分でCSSを書く |
| フォーカスの閉じ込め | 最初から対応 | 自前実装は難しい |
| スクロールの固定 | 最初から対応 | 自分で書く |
| 細かい挙動の制御 | しづらい | 自由にできる |
いちばん差が出るのはフォーカスの扱いです。自前のモーダルはTabキーで背景の要素へ抜けてしまい、キーボードだけで操作している人には「閉じられないのに触れない」状態になります。<dialog> はこれを自動で防ぎます。
要素の表示・非表示を切り替える実装は、CSSとjQueryでアコーディオンを実装するやjQueryでドロップダウンメニューを実装する5つの方法でも同じ考え方で作れます。どちらも <details> やCSSだけの代替を載せています。
クリックされた要素から対象を辿る処理でつまずいたら、jQueryで親要素を取得する方法に .closest() の使い方をまとめています。
▼HTML/CSS/JavaScriptの学習本を探してる方はこちらの記事をどうぞ
