<dialog>を使ってみました
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 2
◆ 今後に期待
いつまにかこんなタグがありました
今まではbodyタグの子要素にこんなの
ですが その前に一応上のサンプルを簡単に説明しておきます
外側divでposition:fixed;width:100%;height:100%で全画面に要素を表示します
fixedなのでスクロールしてもずっと同じ位置に固定されます
この要素が上にあるせいで(おかげで)inputやaなどをクリックしても反応しなくなります
このままだと分かりづらいので背景色をrgba(0,0,0,0.35)にして半透明で暗くします
クリックされたらこの要素を非表示にします
内側divは真ん中にダイアログメッセージを表示する場所を作っているだけです
分かりやすいように背景を白色にしてます
メッセージ表示部分をクリックしてダイアログが消えないようにonclickではstopPropagationを行います
ダイアログを表示させたいときには外側divのdisplayをblockにします
では dialogタグに移ります
dialogタグでは3つ
・show
・showModal
・close
のメソッドが使えます
最初closeというのを見つけたのでopenと試したらそんなメソッドないとエラーが出ました
少し分かりづらいメソッド名です

これだとdialogタグを下の方に書いてるのですごく下に出てきました
さらに 背景のaタグやinputタグにアクセス可能です
alertを表示するボタンを押してみると↓

ダイアログが出てalertダイアログまで出てます
この状態でshowModalを実行するボタンを押してみると
すでにダイアログが開いてるって内容です
ダイアログを出すなら他の要素にさわれなくして欲しいし 表示されたことをわかりやすくして欲しいのでshowメソッドは使いドコロがわからない いらない子です
ダイアログオープン中は他のinputなどを押せない良い仕様です

ですが position:fixed というわけではなく スクロールするとdialogタグがずれます

dialogタグにcssを使えるので position:fixedを自分で設定すれば直せます
他にも真ん中が嫌だから左の方にってこともできます
showModalはできる子!
+++追記+++
showModalはescapeキーでダイアログを閉じてくれます
やっぱりshowModalはできる子!
これを実行しないと閉じてくれません
暗いところをクリックしたら閉じたいときは自分でプログラムを書かないとダメです
方法ですが dialogタグは表示されるとこんなサイズになります

要素が文字を表示する部分(緑色と青色)になっています
じゃあ外側はどうやって取るのということですが dialogタグに対してonclickをつけて確認すると 画面のどこをクリックしてもdialogタグをクリックしたイベントが起きています
じゃあ文字を表示する部分はどうやって取れるの??
少し調べてみたのですが 外と内を分けてクリックイベントを受け取れるon○○○はなさそうでした
なら しょうがない 無理矢理やってやる!
ということでこうなりました
getClientRects()でdialogの内側(文字を表示する部分)の場所と大きさをもってきます
クリックしたところとdialogの位置を比較して外側にあったらdialog.close();を実行しています
「rect &&」 となっているのはdialogタグが非表示のときはdialogタグのgetClientRects()の返り値の[0]がundefinedになるからです
<dialog open></dialog>
と 属性にopenがあるのがダイアログが開いている状態です
直接open属性を削除してもcloseと同じくダイアログが消えます
ですが openを直接つけるのはshowと同じ動きになり showModalにはならないです
Chromodo36だと動かない と思って調べてみると実装されたのがChrome37からなんですね
機能少ないのも納得です
メソッドやイベント増えて使いやすくなっていってほしいですね
サンプル
今まではbodyタグの子要素にこんなの
<div style="position:fixed;width:100%;height:100%;background-color:rgba(0,0,0,0.35)" onclick="this.style.display='none'">
<div style="position:absolute;left:25%;right:25%;top:35%;bottom:35%;background-color:#f0f0f0;" onclick="event.stopPropagation();">
ここがダイアログ
</div>
</div>
を書いてたのが楽になるのかなと期待しながら使ってみますですが その前に一応上のサンプルを簡単に説明しておきます
外側divでposition:fixed;width:100%;height:100%で全画面に要素を表示します
fixedなのでスクロールしてもずっと同じ位置に固定されます
この要素が上にあるせいで(おかげで)inputやaなどをクリックしても反応しなくなります
このままだと分かりづらいので背景色をrgba(0,0,0,0.35)にして半透明で暗くします
クリックされたらこの要素を非表示にします
内側divは真ん中にダイアログメッセージを表示する場所を作っているだけです
分かりやすいように背景を白色にしてます
メッセージ表示部分をクリックしてダイアログが消えないようにonclickではstopPropagationを行います
ダイアログを表示させたいときには外側divのdisplayをblockにします
では dialogタグに移ります
dialogタグでは3つ
・show
・showModal
・close
のメソッドが使えます
document.querySelector("dialog").show();
のような使い方をします最初closeというのを見つけたのでopenと試したらそんなメソッドないとエラーが出ました
少し分かりづらいメソッド名です
show
showはダイアログを表示しますが 場所はHTML的に要素が書かれた場所で 背景も変わらないのでダイアログが出たのかどうかがわかりにくいです
これだとdialogタグを下の方に書いてるのですごく下に出てきました
さらに 背景のaタグやinputタグにアクセス可能です
alertを表示するボタンを押してみると↓

ダイアログが出てalertダイアログまで出てます
この状態でshowModalを実行するボタンを押してみると
Uncaught InvalidStateError: Failed to execute 'showModal' on 'HTMLDialogElement': The element already has an 'open' attribute, and therefore cannot be opened modally.というエラー出ました
すでにダイアログが開いてるって内容です
ダイアログを出すなら他の要素にさわれなくして欲しいし 表示されたことをわかりやすくして欲しいのでshowメソッドは使いドコロがわからない いらない子です
showModal
こっちはよくある 背景が暗くなって 画面の真ん中に出てくるタイプですダイアログオープン中は他のinputなどを押せない良い仕様です

ですが position:fixed というわけではなく スクロールするとdialogタグがずれます

dialogタグにcssを使えるので position:fixedを自分で設定すれば直せます
他にも真ん中が嫌だから左の方にってこともできます
showModalはできる子!
+++追記+++
showModalはescapeキーでダイアログを閉じてくれます
やっぱりshowModalはできる子!
close
closeはshowやshowModalで出したdialogを閉じるものですこれを実行しないと閉じてくれません
暗いところをクリックしたら閉じたいときは自分でプログラムを書かないとダメです
方法ですが dialogタグは表示されるとこんなサイズになります

要素が文字を表示する部分(緑色と青色)になっています
じゃあ外側はどうやって取るのということですが dialogタグに対してonclickをつけて確認すると 画面のどこをクリックしてもdialogタグをクリックしたイベントが起きています
じゃあ文字を表示する部分はどうやって取れるの??
少し調べてみたのですが 外と内を分けてクリックイベントを受け取れるon○○○はなさそうでした
なら しょうがない 無理矢理やってやる!
ということでこうなりました
window.onclick = function(eve){
var dialog = document.querySelector("dialog");
var rect = dialog.getClientRects()[0];
if(rect && (eve.clientX < rect.left
|| eve.clientX > rect.left + rect.width
|| eve.clientY < rect.top
|| eve.clientY > rect.top + rect.height)
){
dialog.close();
}
};
getClientRects()でdialogの内側(文字を表示する部分)の場所と大きさをもってきます
クリックしたところとdialogの位置を比較して外側にあったらdialog.close();を実行しています
「rect &&」 となっているのはdialogタグが非表示のときはdialogタグのgetClientRects()の返り値の[0]がundefinedになるからです
open
メソッドにはopenはないですが 属性にopenがあります<dialog open></dialog>
と 属性にopenがあるのがダイアログが開いている状態です
直接open属性を削除してもcloseと同じくダイアログが消えます
ですが openを直接つけるのはshowと同じ動きになり showModalにはならないです
Chromodo36だと動かない と思って調べてみると実装されたのがChrome37からなんですね
機能少ないのも納得です
メソッドやイベント増えて使いやすくなっていってほしいですね
サンプル