html5のdialog
タグを使ってモーダルウィンドウ実装するとどうなるのか試してみたかった。
firefoxでは使えないみたい。
HTML
クラス構文使って以下の通りに。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
</head>
<body>
<dialog id="dialog">
<p class="message"></p>
<button>OK</button>
<button>CANCEL</button>
</dialog>
<button id="btn1">btn1</button>
<button id="btn2">btn2</button>
<script>
class Modal {
constructor(dialog){
if (dialog.tagName!=='DIALOG') throw 'target is not DIALOG'
if (dialog.classList.contains('modal-instance')) throw 'target is used'
dialog.classList.add('modal-instance')
this.dialog = dialog
this._close = e => e.target.tagName==='BUTTON' && dialog.close(e.target.textContent)
this._after = e => this.fn(e.target.returnValue, ...this.args)
dialog.addEventListener('click', this._close, false)
dialog.addEventListener('close', this._after)
}
open(msg='', fn, ...args){
if (typeof fn!=='function') return
this.dialog.querySelector('.message').textContent = msg
this.dialog.showModal()
this.fn = fn
this.args = args
}
}
const modal = new Modal(document.getElementById('dialog'));
const afterModal = (rv, btnId, a, b) => {
if (rv==='CANCEL') return console.log(rv)
switch (btnId) {
case 'btn1':
console.log(btnId, a+b)
break
case 'btn2':
console.log(btnId, a*b)
break
}
}
document.getElementById('btn1').addEventListener('click', e => {
modal.open('btn1 question', afterModal, 'btn1', 5, 5)
}, false);
document.getElementById('btn2').addEventListener('click', e => {
modal.open('btn2 question', afterModal, 'btn2', 5, 5)
}, false);
</script>
</body>
</html>
javascript解説
class Modal {
constructor(dialog){ //利用したいDIALOGを指定
if (dialog.tagName!=='DIALOG') throw 'target is not DIALOG'
//既に利用されているか確認
if (dialog.classList.contains('modal-instance')) throw 'target is used'
dialog.classList.add('modal-instance')
this.dialog = dialog
//ダイアログ内のボタンを押した時の処理
//ボタンの文字列を取得
this._close = e => e.target.tagName==='BUTTON' && dialog.close(e.target.textContent)
//閉じた後の処理。指定の関数を実行
this._after = e => this.fn(e.target.returnValue, ...this.args)
dialog.addEventListener('click', this._close, false)
dialog.addEventListener('close', this._after)
}
open(msg='', fn, ...args){
//引数1: ダイアログ内で表示するメッセージ
//引数2: 閉じた後に実行する関数。引数=(押したボタンの文字列, ...引数3)
//引数3以降: 引数2の関数で利用する引数
if (typeof fn!=='function') return
this.dialog.querySelector('.message').textContent = msg
this.dialog.showModal()
this.fn = fn
this.args = args
}
}
//以降、使用例
const modal = new Modal(document.getElementById('dialog'));
const afterModal = (rv, btnId, a, b) => {
if (rv==='CANCEL') return console.log(rv)
switch (btnId) {
case 'btn1':
console.log(btnId, a+b)
break
case 'btn2':
console.log(btnId, a*b)
break
}
}
document.getElementById('btn1').addEventListener('click', e => {
modal.open('btn1 question', afterModal, 'btn1', 5, 5)
}, false);
document.getElementById('btn2').addEventListener('click', e => {
modal.open('btn2 question', afterModal, 'btn2', 5, 5)
}, false);
終わり
もっと上手いやり方ありそう。