こんにちは。エキサイトでデザイナーをしている齋藤です。
エキサイトホールディングス Advent Calendar 2024 シリーズ1の9日目を担当します。
今回はAlpine.jsでdialog
タグを制御する方法をご紹介します。
dialogタグとは
dialog
タグはHTML標準のダイアログボックス要素です。2022年3月にFirefoxでもサポートされ、広く使用できるようになりました。
HTML標準ということで、表示されたダイアログは自動的に最上位のレイヤーに移動するためz-index
の調整が不要であったり、esc
キーで閉じられたりと多くのメリットがあります。
一方で制御にはJavaScriptが必要です。
See the Pen Untitled by AyumuSaito (@ayumusaito-excite) on CodePen.
<button id="show-btn" type="button">ダイアログを表示</button> <dialog id="dialog"> <p>ダイアログです</p> <button id="close-btn" type="button">閉じる</button> </dialog> <script> const showTriggerBtn = document.getElementById("show-btn"); const closeTriggerBtn = document.getElementById("close-btn"); const dialog = document.getElementById("dialog"); showTriggerBtn.addEventListener("click", () => { dialog.showModal(); }); closeTriggerBtn.addEventListener("click", () => { dialog.close(); }); </script>
Alpine.jsで制御する
Alpine.jsを使用して制御すると以下のようになります。
See the Pen Untitled by AyumuSaito (@ayumusaito-excite) on CodePen.
<div x-data> <button @click="$refs.dialog.showModal()" type="button">ダイアログを表示</button> <dialog x-ref="dialog"> <p>ダイアログです</p> <button @click="$refs.dialog.close()" type="button">閉じる</button> </dialog> </div>
$refs
を使用してdialog
タグのDOMノードにアクセスしてshowModal()
やclose()
を実行しています。
$refs
については以下の記事も合わせてご覧ください。
コンテンツの外側を押下しても閉じられるようにする
先の例では「閉じる」ボタンを押下しないと非表示にできませんが、コンテンツの外側を押下しても非表示にできるようにすると操作性が向上します。
See the Pen Alpine.jsでdialogを制御(外側押下でも非表示に) by AyumuSaito (@ayumusaito-excite) on CodePen.
<div x-data> <button @click="$refs.dialog.showModal()" type="button">ダイアログを表示</button> <dialog @click.self="$refs.dialog.close()" x-ref="dialog"> <!-- ダイアログのスタイルは.dialog-contentに当てる --> <div class="dialog-content"> <p>ダイアログです</p> <button @click="$refs.dialog.close()" type="button">閉じる</button> </dialog> </div> </div>
まず、dialogタグに@click.self="$refs.dialog.close()"
を付与して、自タグが押下された場合にclose()
が実行されるようにします。
このままですと、コンテンツの部分(今回の場合は文章と「閉じる」ボタン)を押下しても非表示になってしまいます。
そこで、コンテンツの部分をwrapすることで@click.self
による自タグのクリック判定から除外させ、dialog
タグがshowModal()
のときに背後に挿入される疑似要素(::backdrop
)の押下のみが判定されるようにします。
まとめ
今回はAlpine.jsでdialog
タグを制御する方法をご紹介しました。
通常の方法では、HTMLとJSが分離するためどの要素に対する処理なのかが一見分かりづらかったり、他要素への影響に気を使う必要がありました。
一方でAlpine.jsでは、HTMLの属性としてJSの処理を記述するため要素との関係性も分かりやすく、x-data
単位でスコープされるため他要素への影響も気にせずに実装ができるようになりました。
ぜひ、dialog
タグとAlpine.jsの組み合わせをお試しいただければと思います。
ご精読ありがとうございました。