ダイアログの中を押しても閉じないのはなぜ?クリックの伝わり方
背景を押すと閉じるのに、中のボタンを押しても閉じない。実Modalを専用ページで動かし、イベントの伝播と、閉じる処理を直接呼ぶ経路を確認しました。
CONTENTSこの記事の目次5項目
Appli ParkのModalは、背景を押すと閉じる作りです。背景の内側に置かれたダイアログを押しても、同じ閉じる処理が呼ばれないのでしょうか。実部品を専用ページで動かすと、内部ボタンは反応しても開いたままで、背景と閉じるボタンではそれぞれ一度だけ閉じました。
クリックは、押した要素だけで終わるとは限らない
一般的なクリックイベントは、押した要素から親の方へ伝わる段階を持ちます。この伝播をバブリングと呼びます。内部のボタンで発生したクリックも、途中で止めなければ、親の要素に付けた処理まで届く可能性があります。 実Modalは、外側のoverlayにonCloseを指定し、内側のdialogではevent.stopPropagationを呼びます。内部を押したイベントが、そのまま外側の閉じる処理へ届かないようにする構造です。
実部品を使い、三つの場所を押してみる
検証ページには、実Modalと実CSSをコピーし、開くボタンと操作ログだけを追加しました。内部のボタンは「内部ボタンを押した」と記録し、onCloseは呼ばれるたびに別の記録を残します。 最初にダイアログを開いて内部ボタンを押し、次に背景を押しました。もう一度開いて、今度は閉じるボタンを押しました。操作は実ブラウザーで行い、DOMにダイアログが残るかも確認しました。
| 押した場所 | onCloseの追加呼び出し | ダイアログ |
|---|---|---|
| 内部ボタン | 0回 | 開いたまま |
| 背景 | 1回 | 閉じる |
| 開き直した後の閉じるボタン | 1回 | 閉じる |
閉じるボタンは、伝わる前に自分で呼ぶ
閉じるボタンもdialogの内側にあります。それでも閉じられるのは、このボタン自身のonClickがonCloseを呼ぶためです。その後、dialogで親への伝播が止まります。 つまり「中で発生したクリックは全部無効」ではありません。内部のボタンの仕事は実行し、背景用の処理まで余計に届かせない、という分担です。今回も内部ボタンの操作ログは残りました。
stopPropagationとpreventDefaultは別の操作
stopPropagationは、そのイベントがさらに伝わることを止めます。一方、preventDefaultは、リンクの移動やフォームの送信など、その操作に用意された既定の動作を取り消すためのものです。 たとえばリンクのクリックで伝播を止めても、それだけでリンク先への移動を取り消すとは限りません。実Modalのキーボード処理にはpreventDefaultも出てきますが、クリックが背景へ届くのを止める処理と同じ役割ではありません。
閉じ方を調べるときは、呼ばれる経路を描く
どの要素がクリックを受け、どの要素まで伝わり、どこで閉じる関数を直接呼ぶか。この三つを図にすると、内部の操作で誤って閉じる理由や、閉じる処理が重複する理由を追いやすくなります。 今回確かめたのは、このModalの三つのクリック経路です。すべての入力方法や支援技術を検証した記事ではありません。画面が閉じるかという見た目から、実際に呼ばれた処理へ戻して確認しました。
実Modalのクリック処理と専用ページの操作記録を照合しました。
出典・参考資料Event: stopPropagation() methodMDN Web Docs。イベント伝播の停止と、既定動作を取り消すpreventDefaultとの違い。 リンク先確認:2026年10月4日。developer.mozilla.org確認日:2026年9月22日。実装・検証結果・公式資料は確認時点のものです。