この記事で分かること
- dialog要素でEscキーでcloseした際にoverflow:hiddenを解除する方法
- dialog要素を使う利点、懸念点
背景
ダイアログをdialogタグで記述した際にescキーで閉じることができます(ブラウザーによって提供)。
しかし、overflow:hiddenを解除できなかったのでモーダルが消えてもスクロールができません。
そこでどうしたら良いか考えてみました。
補足)showModal() メソッドによって呼び出された<dialog>
は、Escキーによって閉じることができます。
実装
openModal(){
document.body.style.overflow = 'hidden';
const modalElm = this.getModalElm();
if (!(modalElm instanceof HTMLDialogElement)) return;
modalElm.showModal();
}
以下の実装を当初は考えてました。
しかし、これだとキーを打つたびに毎回この処理が走るので良くないですね。
registerCanselModalEvent() {
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
document.body.toggleAttribute('style');
}
});
};
このブログでcancelイベントというのを知りました。
dialog要素を使う今後のモーダル実装
The cancel event is fired by and elements. The event is fired when the user cancels the currently open dialog by closing it with the Esc key
mdnによると
dialogを開いている際にEscキーを押したらcancelイベントが発生する
と記載があります。
こちらを採用したいと思います!
registerCancelModalEvent() {
const dialog = document.querySelector('dialog');
if (dialog) {
dialog.addEventListener("cancel", (event: Event) => {
if (event.currentTarget === dialog) {
document.body.toggleAttribute('style');
}
});
}
}
inputタグをEscで閉じた際もcanselイベントが発生するので、Event.currentTarget
を使っています。
補足
紹介した方もブログで書かれてましたが、以下の点でdialogタグは利点があります。
直感的な記述かつ実装が簡潔
今まで<div role="dialog">
で記述して実装していましたがコード量が減ります。
modal.showModal();
- モーダルを表示します。
- CSS の ::backdrop 擬似要素を使用して、 要素が HTMLDialogElement.showModal() で表示されたときの背後のスタイルを設定することができます
例)ダイアログの背後にある操作できないコンテンツを暗くする
modal.close();
- モーダルを閉じます。
- backdropが消えます。
デフォルトでEscキーで閉じることができる
cancelイベントを扱って実装ができる
懸念点
IEでは使えないです。
デフォルトだとモーダルより下はスクロールしてしまいます。
今回のような実装はしないといけないですね。
- modal.close()
- Escキー押下時