JavaScript

ダイアログを背景クリックで閉じる。背景に×バツ印

dialogの背景に×バツ印を配置したい。
iOSはdialogのコンテンツ領域外は overflow: hidden; の様な挙動になる。
iOSの現象なのか、Macもそうなのか、Safariだけの現象なのかは忘れたが、とにかく解決方法を示す。

↑答えはここにあります

×

<dialog>の背景に×印を配置するには、2枚のdialogを重ねて対応。

現時点のコードは以下の通り:
/**
 * modal dialog open close
 *
 * author ao-system, Inc.
 * date 2024-04-13
 *
 *
<style>
dialog#dialogBack01 {
	border: none;
	background-color: transparent;
	&::backdrop {
		background-color: rgba(0,0,0,0.5);
	}
	> div {
		position: fixed;
		right: 10px;
		top: 10px;
		font-size: 2.0rem;
		font-weight: 900;
		line-height: 1;
		color: #fff;
	}
}
dialog#dialog01 {
	padding: 0;
	border: none;
	&::backdrop {
		background-color: transparent;
	}
	> div {
	}
}
</style>

<dialog id="dialogBack01"><div>×</div></dialog>
<dialog id="dialog01">
	<div>
		コンテンツ
	</div>
</dialog>
 *
 */
(() => {
	new class {
		'use strict';
		#dialogOpen		= document.getElementById('dialogOpen01');
		#dialogBack		= document.getElementById('dialogBack01');
		#dialogBody		= document.getElementById('dialog01');
		constructor() {
			//開くボタンのクリック
			this.#dialogOpen.addEventListener('click', () => {
				this.#dialogBack.showModal();
				this.#dialogBody.showModal();
				//フェードインで開く
				this.#dialogBody.animate(
					[
						{opacity:0},
						{opacity:1},
					],
					{duration:300,fill:'forwards'}
				);
			});
			//ブラウザ内のクリック
			//クリックされた場所の親を辿り、ダイアログの前景(内側のdiv)だったら何もしない。
			//ダイアログ自身(この場合はダイアログの背景)だったら閉じる。
			this.#dialogBody.addEventListener('click',(event) => {
				let tgt = event.target;
				for (let i = 0; i < 99; i++) {	//whileで回さずforなのは99回のリミッターを付けたため。記述ミスやブラウザの仕様変更やバグで無限ループを防ぐ。
					if (tgt == this.#dialogBody.querySelector('div')) {
						return;
					} else if (tgt == this.#dialogBody) {
						this.#dialogBody.close();
						this.#dialogBack.close();
						return;
					}
					if (tgt.parentNode) {
						tgt = tgt.parentNode;
					} else {
						return;
					}
				}
			});
		}
	}
})();
2024年3月初版
このサイトについてのお問い合わせはエーオーシステムまでお願いいたします。
ご使用上の過失の有無を問わず、本プログラムの運用において発生した損害に対するいかなる請求があったとしても、その責任を負うものではありません。