Invoker Commands APIでJavaScriptなしでボタンから他の要素を操作する
Invoker Commands APIを使うと、commandforとcommand属性だけでDialogやPopoverを操作できます。commandイベントを利用することで、独自のカスタムコマンドを定義することも可能です。
はじめに
これまで、Dialogをモーダルで開くにはJavaScriptで<dialog>要素のshow()・showModal()メソッドを呼び出す必要がありました。
openButton.addEventListener('click', () => {
dialog.showModal(); // or dialog.show();
});
Baseline 2025で追加されたInvoker Commands APIを使えば、これがHTML属性だけで実現できます。
<button commandfor="my-dialog" command="show-modal">開く</button>
<dialog id="my-dialog">Dialogの内容</dialog>
Popover APIのpopovertarget属性とpopovertargetaction属性と同じ考え方で、より一般化してDialog等も宣言的に操作できるようになりました。
基本的な使い方
Invoker Commands APIはcommandforとcommandの2つの属性で構成されます。
<button commandfor="my-dialog" command="show-modal">開く</button>
<dialog id="my-dialog">Dialogの内容</dialog>
commandforは操作対象の要素のidを指定、commandは実行するアクションを指定します。
commandは現在カスタム値を除いて、Dialogのshow-modal・close・request-close、Popoverのshow-popover・hide-popover・toggle-popoverが使えます。
ボタンをクリックすると、commandforで指定した要素に対してJavaScriptのshowModal()・close()・requestClose()、showPopover()・hidePopover()・togglePopover()メソッド相当の動作が実行されます。
Dialogの操作
<button commandfor="dialog" command="show-modal">Dialogを開く</button>
<dialog id="dialog">
<p>Dialogの内容</p>
<button commandfor="dialog" command="close">閉じる</button>
</dialog>
Playground
Popoverの操作
<button commandfor="popover" command="toggle-popover">メニュー</button>
<div id="popover" popover>
ポップオーバーの内容
</div>
ポップオーバーの場合、従来のpopovertargetとpopovertargetaction属性でも同じことができます。
<button popovertarget="popover" popovertargetaction="toggle">メニュー</button>
<div id="popover" popover>
ポップオーバーの内容
</div>
Playground
Invoker Commands API
Popover API
Popoverの内容
どちらのボタンでも同じPopoverを操作できます。
カスタムコマンド
show-modalやtoggle-popoverのような組み込みコマンドだけでなく、独自のコマンドを定義することもできます(これにはJavaScriptが必要です)。
カスタムコマンドは--で始まる名前で定義します。
<button commandfor="my-image" command="--zoom-in">拡大</button>
<button commandfor="my-image" command="--zoom-out">縮小</button>
<button commandfor="my-image" command="--reset">リセット</button>
<img id="my-image" src="photo.jpg" alt="写真" />
カスタムコマンドはcommandイベントで処理します。
const image = document.getElementById('my-image');
let scale = 1;
image.addEventListener('command', (event) => {
if (event.command === '--zoom-in') {
scale = Math.min(scale + 0.25, 2);
} else if (event.command === '--zoom-out') {
scale = Math.max(scale - 0.25, 0.5);
} else if (event.command === '--reset') {
scale = 1;
}
image.style.scale = `${scale}`;
});
commandに応じた自由な動作を実装できます。commandに--ではじまらない名前を渡した場合はevent.commandに値がセットされないので注意してください。
Playground

カスタムコマンド(--zoom-in、--zoom-out、--reset)で操作しています。
おわりに
Invoker Commands APIを紹介しました。
commandforとcommand属性を使うことで、JavaScriptを書かずにDialogやPopoverを宣言的に操作できます。Popover APIのpopovertarget属性と同じ考え方が、Dialogにも適用できるようになったのは嬉しいですね。
また、--で始まるカスタムコマンドとcommandイベントを組み合わせれば、組み込みコマンドでカバーできない独自の操作も実装できます。
Baseline 2025で全ブラウザ対応となったので、ぜひ活用してみてください。