JavaScriptでダイアログボックスを表示するとき、一般的にはalert()
, confirm()
, prompt()
などのメソッドを使います。ただし、この方法で表示させるダイアログはカスタマイズができないんですよね。
この記事では、HTMLの<dialog>
要素を使ってダイアログボックスを作り、JavaScriptで制御する方法を解説します。ダイアログボックスの見た目や表示内容をオシャンティにカスタマイズできちゃいます。
dialog要素とは
<dialog>
はウェブページにダイアログボックスを表示するためのHTML要素です。次のように記述します。
<dialog open>
<p>一度入信したら、もう後戻りはできません。</p>
<button>OK</button>
</dialog>
上記の例では<dialog>
要素の中に<p>
と<button>
を入れましたが、何でも入れることができます。見出しをつけたり、フォームとか画像とか表とか何でもOKです。
<dialog>
要素にopen
属性を指定するとダイアログが表示されます。open
属性を指定しなければ非表示になります。ただし、このopen
属性を使うのは非推奨となっています。ダイアログの表示・非表示を制御するにはJavaScriptのshow()
およびclose()
メソッドを使います。
ダイアログをJavaScriptで制御する
ダイアログの表示と非表示
ダイアログの表示・非表示を制御するには、JavaScriptのshow()
およびclose()
メソッドを使います。
<dialog id="myDialog">
<p>一度入信したら、もう後戻りはできません。</p>
<button class="button ok">OK</button>
</dialog>
<button id="showButton">ダイアログを開く</button>
<script>
//各要素を変数に代入
const dialog = document.querySelector('#myDialog');
const okButton = document.querySelector('#myDialog .button.ok');
const showButton = document.querySelector('#showButton');
//「ダイアログを開く」ボタンがクリックされたらダイアログを開く
showButton.addEventListener('click', function () {
dialog.show();
});
//「OK」ボタンがクリックされたらダイアログを閉じる
okButton.addEventListener('click', function () {
dialog.close();
});
</script>
16行目、dialog.show();
でダイアログが開きます。そして20行目、dialog.close();
でダイアログが閉じます。
モーダルダイアログとモードレスダイアログ
ダイアログにはモーダルダイアログとモードレスダイアログがあります。これらの違いを理解して、適切なダイアログ設計をしましょう。
モーダルダイアログ | モードレスダイアログ | |
---|---|---|
概要 | ダイアログを開いている間は、親ページの操作ができない | ダイアログを開いている間も、親ページの操作ができる |
ダイアログの背景 | 暗くなる | 暗くならない |
親ウインドウをスクロールしたとき | 追従しない | 追従する |
escキーを押したとき | 閉じる | 閉じない |
で、上記で解説したshow()
メソッドで開くダイアログは、モードレスダイアログです。モーダルダイアログを開くにはshowModal()
メソッドを使います。
dialog.showModal();
closeイベントとcancelイベント
ダイアログを閉じるとcloseイベントが発生します。これはイベントリスナーやイベントハンドラで使うことができます。
//イベントリスナーを使う例
dialog.addEventListener('close', function () {
alert('closeイベントが発生しました');
});
//イベントハンドラを使う例
dialog.onclose = function () {
alert('closeイベントが発生しました');
};
モーダルダイアログを閉じるためにキーボードのescキーを押すとcancelイベントが発生します。
//イベントリスナーを使う例
dialog.addEventListener('cancel', function () {
alert('cancelイベントが発生しました');
});
//イベントハンドラを使う例
dialog.oncancel = function () {
alert('cancelイベントが発生しました');
};
ダイアログを閉じたときの戻り値
ダイアログに2つ以上のボタンがあって、どのボタンがクリックされたかを判別したいときがあります。そのような場合はclose()
メソッドに引数を与えることで戻り値を受け取ることができます。
<dialog id="myDialog">
<p>本当に入信しますか?</p>
<button class="button cancel">キャンセル</button>
<button class="button ok">OK</button>
</dialog>
<button id="showButton">ダイアログを開く</button>
<script>
//各要素を変数に代入
const dialog = document.querySelector('#myDialog');
const cancelButton = document.querySelector('#myDialog .button.cancel');
const okButton = document.querySelector('#myDialog .button.ok');
const showButton = document.querySelector('#showButton');
//「ダイアログを開く」ボタンがクリックされたらダイアログを開く
showButton.addEventListener('click', function () {
dialog.showModal();
});
//キャンセルがクリックされたらダイアログを閉じてcancelを返す
cancelButton.addEventListener('click', function () {
dialog.close('cancel');
});
//OKがクリックされたらダイアログを閉じてokを返す
okButton.addEventListener('click', function () {
dialog.close('ok');
});
//closeイベントが発生したらalertで戻り値を表示
dialog.addEventListener('close', function () {
alert('returnValue: ' + dialog.returnValue);
});
</script>
22行目でclose()
メソッドに引数'cancel'
を、26行目では引数'ok'
を与えています。close()
メソッドが実行されるとそれぞれの引数が戻り値として返されます。戻り値はreturnValue
プロパティに格納されます。
31行目のようにdialog.returnValue
で参照することができます。
ダイアログボックスの外側をクリックして閉じる
ここまで、ダイアログボックスを閉じるにはボタンのクリックまたはescキーを使いました。もし、ダイアログボックスの外側をクリックして閉じることができたら嬉しくないですか?私は嬉しいです。
<dialog id="myDialog">
<div class="inner">
<p>一度入信したら、もう後戻りはできません。</p>
<button class="button ok">OK</button>
</div>
</dialog>
<button id="showButton">ダイアログを開く</button>
<style>
#myDialog {
padding: 0;
}
#myDialog .inner {
padding: 1em;
}
</style>
<script>
//各要素を変数に代入
const dialog = document.querySelector('#myDialog');
const okButton = document.querySelector('#myDialog .button.ok');
const showButton = document.querySelector('#showButton');
//「ダイアログを開く」ボタンがクリックされたらダイアログを開く
showButton.addEventListener('click', function () {
dialog.showModal();
});
//「OK」ボタンがクリックされたらダイアログを閉じる
okButton.addEventListener('click', function () {
dialog.close();
});
//ダイアログの外側がクリックされたらダイアログを閉じる
dialog.addEventListener('click', function (event) {
if (!event.target.closest('#myDialog .inner')) {
dialog.close();
}
});
</script>
2, 5行目、<dialog>
要素の内側に<div class="inner">
を記述しておきます。この<div class="inner">
の親要素(外側)がクリックされたときにダイアログが閉じるようにJavaScriptで制御します。
11〜16行目、#myDialog
のpadding
を0
にして、#myDialog .inner
がダイアログボックス内に目一杯広がるようにします。そして#myDialog .inner
の内側に適度なpadding
を設定します。
34〜38行目、#myDialog .inner
の外側がクリックされたときにダイアログを閉じるための記述です。closest()
は、その要素と祖先要素を指定したセレクタで探索するメソッドです。この場合、クリックした位置(event.target
)の祖先要素を取得し#myDialog .inner
でなければダイアログを閉じます。
説明してて、難しいよなぁ伝わってるかなぁと思ってます。わからなかったらコピペすればいいぢゃない。
ダイアログの背景がスクロールしないようにする
デフォルトでは、ダイアログを開いているときでもその後ろの親ウインドウはスクロールできてしまいます。もし、親ウインドウを固定できたら嬉しくないですか?私は嬉しいです。
<dialog id="myDialog">
<p>一度入信したら、もう後戻りはできません。</p>
<button class="button ok">OK</button>
</dialog>
<button id="showButton">ダイアログを開く</button>
<style>
body.inactive {
overflow: hidden;
}
</style>
<script>
//各要素を変数に代入
const body = document.body;
const dialog = document.querySelector('#myDialog');
const okButton = document.querySelector('#myDialog .button.ok');
const showButton = document.querySelector('#showButton');
//「ダイアログを開く」ボタンがクリックされたらinactiveクラスを追加してモーダルダイアログを開く
showButton.addEventListener('click', function () {
body.classList.add('inactive');
dialog.showModal();
});
//「OK」ボタンがクリックされたらinactiveクラスを削除してダイアログを閉じる
okButton.addEventListener('click', function () {
body.classList.remove('inactive');
dialog.close();
});
//escキーが押されたらinactiveクラスを削除
dialog.addEventListener('cancel', function () {
body.classList.remove('inactive');
});
</script>
9〜11行目、<body>
要素にinactive
クラスがついていたらスクロールできないようにするための設定です。
16行目、<body>
要素を変数に入れておきます。
23行目、ダイアログを開いたら<body>
要素にinactive
クラスを追加します。これで<body>
がスクロールできなくなります。
28行目、ダイアログを閉じたら、<body>
要素からinactive
クラスを削除します。これで<body>
がスクロールできるようになります。
32〜34行目、escキーでダイアログを閉じた場合にもinactive
クラスを削除します。
無料で利用できるプログラミング学習サービスをお探しならば Code Lesson はいかがでしょうか。プロのエンジニアが監修した学習ロードマップで効率的に学習、AIに質問、最後にクイズで理解度をチェックできます。
ダイアログをCSSでスタイリングする
ずっと気になっていたとは思いますが、デフォルトの<dialog>
のデザインはとてもダサいです。CSSで外観をカスタマイズしましょう。
ダイアログボックスの外観は一般的なブロック要素と同じようにスタイリングできます。縦横のサイズとか色とかボーダーとか影とか位置とか。ここでは詳しく解説しません(冷たい)。
そして、ダイアログ特有の要素は::backdrop
擬似要素です。ダイアログをshowModal()
で開いたときの背景をスタイリングすることができます。デフォルトでは、モーダルダイアログを開くと背景にうっすらと影がかかります。この影をもっと濃くしたいならば次のようにします。
<style>
#myDialog::backdrop {
background-color: rgba(0, 0, 0, 0.4);
}
</style>
いろいろなダイアログのスタイリング例は下記の記事でどうぞ。
さいごに
というわけで、HTMLの<dialog>
要素とJavaScriptとCSSでダイアログを簡単に自作できることがおわかりいただけたかと思います。
ウェブサイトの価値はダイアログのオシャレ度で決まると言われています(どこで)。ぜひ、かっこいいダイアログの作成にチャレンジしてみてください。
でわでわ
コメント