Dialog を Modal で使うための最小のコード

<b>この記事は dialog を使ってるので Chrome でみてください。</b>

# 最小のコード

HTML で Modal Dialog を使う最小のコードはこんな感じ。

```html
<dialog id=Dialog>
    Hello<br>
    <input id=DialogCancel type=button value=Cancel>
</dialog>
<input id=OpenDialog type=button value=Open>
<br>
Result: <span id=Result></span>
```

```javascript
const I = $ => document.getElementById( $ )
const dialog = I( 'Dialog' )
I( 'DialogCancel' ).onclick = ev => dialog.close( 'Cancel' )
I( 'OpenDialog'   ).onclick = ev => {
  dialog.showModal()
  dialog.oncancel = ev => dialog.close( 'Escape' ) 
  dialog.onclose  = ev => I( 'Result' ).textContent = dialog.returnValue
}
```
こうすると以下の2つの場合にダイアログは終了する。

* ボタンが押された時
* エスケープキーが押された時

ボタンの onclick でダイアログをクローズしてやって、その時に引数に渡したものが dialog の onclose 時に returnValue に入ってくるのでそれで何ボタンが押されたか判断すればいい。

エスケープキーが押された場合のために、dialog の oncancel で close に何か（ここでは Escape という文字列）を渡す。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="satachito" data-slug-hash="GRpgwwQ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="GRpgwwQ">
  <span>See the Pen <a href="https://codepen.io/satachito/pen/GRpgwwQ">
  GRpgwwQ</a> by Satachito (<a href="https://codepen.io/satachito">@satachito</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# バックドロップのクリックで閉じたい場合

バックドロップ（モーダルダイアログが出てる時のページの輝度の下がっている部分）でクリックされた時も閉じたい場合はちょっと工夫がいる。以下輝度の下がっていない部分は「本体」

```html
<dialog id=Dialog>
  <div>
    Hello<br>
    <input id=DialogCancel type=button value=Cancel>
  </div>
</dialog>
<input id=OpenDialog type=button value=Open>
<br>
Result: <span id=Result></span>
```

```css
dialog {
; padding : 0 
}
```

```javascript
  const I = $ => document.getElementById( $ )
  const dialog = I( 'Dialog' )
  I( 'DialogCancel' ).onclick = ev => dialog.close( 'Cancel' )
  dialog.onclick              = ev => ev.target == dialog ? dialog.close( 'Backdrop' ) : void 0
  I( 'OpenDialog'   ).onclick = ev => {
    dialog.showModal()
    dialog.oncancel = ev => dialog.close( 'Escape' ) 
    dialog.onclose  = ev => I( 'Result' ).textContent = dialog.returnValue
  }
```

* dialog の onclick で ev.target に実際にクリックされたエレメントが入ってくる。
* バックドロップも dialog の一部なので、クリックされた場合 ev.target は dialog になる。
* dialog の本体がクリックされた場合、直下の div が本体全体を覆っているので ev.target は直下の div になる。
* なので dialog の onclick で、ev.target が dialog であればバックドロップでクリックされている。

ここで注意点は以下の2つ

* dialog の直下に div を置く
* dialog の padding を 0 にする

これをやらないと本体の余白の部分でクリックした時も close してしまう。

padding が必要な場合は、直下の div につけてやればいい。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="satachito" data-slug-hash="LYpEXPY" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="LYpEXPY">
  <span>See the Pen <a href="https://codepen.io/satachito/pen/LYpEXPY">
  LYpEXPY</a> by Satachito (<a href="https://codepen.io/satachito">@satachito</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>