HTML 5.2では、ネイティブモーダルウィンドウ用の新しいダイアログ要素が導入されました。 一見、非常にシンプルなように見えますが(実際は)、遊んでみたところ、見逃せない素晴らしい機能がいくつかあることがわかりました。
記事の最後に本格的なデモを埋め込みましたが、読んでいるときにそれを見たい場合は、ここで見つけることができます 。
ダイアログボックスの基本的なマークアップの例を次に示します。
<dialog open> Native dialog box! </dialog>
open属性は、ダイアログが表示されることを意味します。 この属性がない場合、JavaScriptを使用してダイアログを表示するまでダイアログは非表示になります。 スタイルを設定しないと、ダイアログは次のようになります。
![](https://habrastorage.org/webt/-m/3o/il/-m3oilkmpn-7zievyxbk_keyikc.png)
ページ上で、それは絶対に配置されるため、すべてのコンテンツの前に表示されるようになり、水平に中央揃えされます。 デフォルトでは、その幅は内部のコンテンツの幅に等しくなります。
基本操作
JavaScriptには、 ダイアログ要素の操作を簡単にするためのいくつかのメソッドとプロパティがあります。 showModal()およびclose()は、最も必要な2つのメソッドです。
const modal = document.querySelector('dialog'); // ( "open") modal.showModal(); // ( "open") modal.close();
showModal()を使用してダイアログを開くと、モーダルウィンドウ外のコンテンツとのユーザーの対話をブロックする背景がページに追加されます。 デフォルトでは、背景は完全に透明ですが、CSSを使用して背景を表示できます(これについては以下で詳しく説明します)。
Escを押すとダイアログが閉じます。また、 close()メソッドを呼び出して閉じるボタンを作成することもできます。
3番目のメソッドshow()があります。これはモーダルウィンドウも表示しますが、背景は付随しません。 ユーザーは、ダイアログ外の要素と対話できます。
ブラウザのサポートとポリフィル
ダイアログは現在Chromeでのみサポートされています。 Firefoxは基本的なスタイル設定を提供しますが、JavaScript APIを使用するには、ユーザーがこの機能を明示的に有効にする必要があります。 Firefoxはすぐにデフォルトで有効になると思います。
幸いなことに、JavaScriptの動作とデフォルトのスタイリングの両方をサポートするポリフィルがあります。 使用するには、 dialog-polyfillをnpmに設定するか、古き良きスクリプトタグを使用します。 ポリフィルはIE9以降で動作します。
ポリフィルを使用する場合、ページ上の各ダイアログを初期化する必要があります。
dialogPolyfill.registerDialog(modal);
このトリックは、それをサポートするブラウザーのダイアログのネイティブな動作を置き換えません。
様式化
モーダルウィンドウを開いたり閉じたりするのはいいことですが、あまり専門的ではありません。 スタイリングの追加は、他の要素のスタイリングと同じくらい簡単です。 背景は、新しい擬似要素:: backdropを使用してスタイル設定できます。
dialog { padding: 0; border: 0; border-radius: 0.6rem; box-shadow: 0 0 1em black; } dialog::backdrop { /* */ background-color: rgba(0, 0, 0, 0.4); }
ポリフィルを使用する古いブラウザの場合、この擬似要素は機能しません。 この場合、ポリフィルは.backdrop要素を追加します。これはダイアログのすぐ後に続きます。 次のようなCSSでスタイルを設定できます。
dialog + .backdrop { background-color: rgba(0, 0, 0, 0.4); }
スタイリング用にもう少しマークアップを追加します。 一般的なアプローチ:ダイアログボックスをヘッダー、本文、およびフッターに分割します。
<dialog id="demo-modal"> <h3 class="modal-header">A native modal dialog box</h3> <div class="modal-body"> <p>Finally, HTML has a native dialog box element! This is fantastic.</p> <p>And a polyfill makes this usable today.</p> </div> <footer class="modal-footer"> <button id="close" type="button">close</button> </footer> </dialog>
いくつかのCSSを追加することで、モーダルウィンドウを必要に応じて正確に表示できます。
![](https://habrastorage.org/webt/pz/89/wr/pz89wrbpmf427i7ksggor33tvck.png)
より詳細な制御
多くの場合、ダイアログボックスを介してユーザーから少しフィードバックが必要です。 ダイアログが閉じたら、文字列値をclose()メソッドに渡すことができます。 この値は、DOM ダイアログ要素のreturnValueプロパティに割り当てられるため、 後で読むことができます。
modal.close('Accepted'); console.log(modal.returnValue); // `Accepted`
購読できる他のイベントもあります。 2つの非常に便利なもの: close (ウィンドウが閉じるときにトリガー)とcancel (Escを押してウィンドウを閉じるとトリガー)。
唯一欠けているのは、背景をクリックしたときにモーダルウィンドウを閉じる機能ですが、回避策があります。 背景をクリックすると、ターゲット要素と同様にダイアログでクリックイベントがトリガーされます。 また、ダイアログボックスのスペース全体に子が表示されるようにダイアログを作成すると、これらの子はダイアログ内のクリックの対象になります。 したがって、ダイアログのクリックのイベントをサブスクライブし、クリックの直接の目標がダイアログウィンドウ自体である場合にそれを閉じることができます。
modal.addEventListener('click', (event) => { if (event.target === modal) { modal.close('cancelled'); } });
完全ではありませんが、機能します。 バックグラウンドのクリックを追跡するためのより良い方法を見つけたら教えてください。
作業デモ
私は以下のデモで多くの仕事をしました。 それをいじって、 ダイアログ要素で他に何ができるかを見てください。 デモにはポリフィルが含まれているため、ほとんどのブラウザーで動作します。
デモへのリンク。