Dialogの背景をクリックしたい
HTML 5.2で追加されたDialog要素は、まだChromeでしかデフォルトで使うことが出来ません。
しかし、タグを追加してちょっと表示するだけでいい感じのモーダルが表示できるので、今後他のブラウザでも実装され次第積極的に使いたいと思っています。
が、このダイアログ、背景の半透明の部分をクリックしても閉じたりできません。
今回はこいつの背景にクリックイベントを割り当てたいと思います。
Dialog要素の背景について
Dialog要素の背景はCSSを見ればわかりますが、疑似要素です。
dialog::backdrop
こいつがいい感じに半透明になって背景にいます。色を濃くしたい場合はCSSで::backdrop
疑似要素に対してスタイルを当てましょう。
本題としてはこれの当たり判定を取りたいところですが、一つ問題があります。疑似要素はスタイルの補助みたいな感じなので、JSで要素を探して直にクリックなどのイベントを割り当てることは出来ません。
しかし、Dialog要素にクリックイベントを追加すると、疑似要素をクリックしたときにも親がクリックされたかのように反応します。
ならば、中にコンテンツ用の要素を仕込み、そいつのクリックイベントを伝播しないように食い止めれば、背景とコンテンツの判定を分けることができそうです。
実装
<style>dialog { padding: 0; }</style>
<dialog>
<div class="contents">test</div>
</dialog>
const dialog = document.querySelector( 'dialog' );
dialog.addEventListener( 'click', (event) =>
{
console.log( 'Background' );
}, false );
contents = dialog.querySelector( '.contents' );
contents.addEventListener( 'click', ( event ) =>
{
event.stopPropagation(); // ここでクリックイベントを止める
console.log( 'Contents' );
}, false );
めでたく背景とコンテンツのクリックイベントを分けて取得できました。
まとめ
とりあえず肝は親要素に設定されている疑似要素にはクリックイベントなどをしかけられないが、親要素にクリックイベントを割り当てると疑似要素クリック時にも反応するという挙動かなと思います。
コンテンツ用に階層が一つ増えますが、そこはまぁ許容しましょう。