この記事は dialog を使ってるので Chrome でみてください。
最小のコード
HTML で Modal Dialog を使う最小のコードはこんな感じ。
<dialog id=Dialog>
Hello<br>
<input id=DialogCancel type=button value=Cancel>
</dialog>
<input id=OpenDialog type=button value=Open>
<br>
Result: <span id=Result></span>
const I = $ => document.getElementById( $ )
const dialog = I( 'Dialog' )
I( 'DialogCancel' ).onclick = ev => dialog.close( 'Cancel' )
I( 'OpenDialog' ).onclick = ev => {
dialog.showModal()
dialog.oncancel = ev => dialog.close( 'Escape' )
dialog.onclose = ev => I( 'Result' ).textContent = dialog.returnValue
}
こうすると以下の2つの場合にダイアログは終了する。
- ボタンが押された時
- エスケープキーが押された時
ボタンの onclick でダイアログをクローズしてやって、その時に引数に渡したものが dialog の onclose 時に returnValue に入ってくるのでそれで何ボタンが押されたか判断すればいい。
エスケープキーが押された場合のために、dialog の oncancel で close に何か(ここでは Escape という文字列)を渡す。
See the Pen GRpgwwQ by Satachito (@satachito) on CodePen.
バックドロップのクリックで閉じたい場合
バックドロップ(モーダルダイアログが出てる時のページの輝度の下がっている部分)でクリックされた時も閉じたい場合はちょっと工夫がいる。以下輝度の下がっていない部分は「本体」
<dialog id=Dialog>
<div>
Hello<br>
<input id=DialogCancel type=button value=Cancel>
</div>
</dialog>
<input id=OpenDialog type=button value=Open>
<br>
Result: <span id=Result></span>
dialog {
; padding : 0
}
const I = $ => document.getElementById( $ )
const dialog = I( 'Dialog' )
I( 'DialogCancel' ).onclick = ev => dialog.close( 'Cancel' )
dialog.onclick = ev => ev.target == dialog ? dialog.close( 'Backdrop' ) : void 0
I( 'OpenDialog' ).onclick = ev => {
dialog.showModal()
dialog.oncancel = ev => dialog.close( 'Escape' )
dialog.onclose = ev => I( 'Result' ).textContent = dialog.returnValue
}
- dialog の onclick で ev.target に実際にクリックされたエレメントが入ってくる。
- バックドロップも dialog の一部なので、クリックされた場合 ev.target は dialog になる。
- dialog の本体がクリックされた場合、直下の div が本体全体を覆っているので ev.target は直下の div になる。
- なので dialog の onclick で、ev.target が dialog であればバックドロップでクリックされている。
ここで注意点は以下の2つ
- dialog の直下に div を置く
- dialog の padding を 0 にする
これをやらないと本体の余白の部分でクリックした時も close してしまう。
padding が必要な場合は、直下の div につけてやればいい。
See the Pen LYpEXPY by Satachito (@satachito) on CodePen.