auxclick が Chrome 55 に登場

クリックが click に該当しないのはどのような場合ですか。複雑なユーザー インターフェースに取り組むウェブ デベロッパーにとって、それは抽象的な哲学的な問題とは言えません。カスタムのマウス入力動作を実装する場合は、ユーザーの意図を念頭に置くことが重要です。たとえば、マウスの中央ボタンがクリックされたリンクをユーザーがクリックした場合、そのリンクのコンテンツを含む新しいタブを開くのは妥当な動作です。ユーザーがランダムな UI 要素をミドルクリックした場合、意図せずその入力を無視したと想定し、メインボタンのクリックで UI からのレスポンスがトリガーされることを想定したほうがよい場合があります。

こうした微妙なインタラクションを 1 つの click イベント リスナーでモデル化することは、やや面倒な作業になることがあります。MouseEventbutton プロパティを明示的にチェックして、プライマリ ボタン(他のボタンではなく)が 0 に設定されているかどうか、通常は 1 が中央のボタンであるなどかどうかを確認する必要があります。しかし、多くのデベロッパーが button プロパティを明示的にチェックしているわけではないため、どのボタンが押されたかにかかわらず、すべての click をまったく同じように処理するコードになってしまいます。

Chrome 55 以降では、メイン以外のボタンで行われたクリックに応答して、auxclick という新しいタイプの MouseEvent が呼び出されます。この新しいイベントに伴って、click イベントの動作も変更されます。このイベントが発生するのは、マウスの左ボタンが押されたときにのみです。この変更により、ウェブ デベロッパーは MouseEvent.button プロパティを確認することなく、目的のクリックのみに応答するイベント ハンドラを簡単に作成できるようになります。

誤検出を低減

前述のように、auxclick を作成する理由の 1 つは、「middle-click-opens-a-tab」動作を誤ってオーバーライドするカスタム click ハンドラをデプロイしないようにすることでした。たとえば、History API を使用してロケーション バーを書き換え、カスタムの単一ページ ナビゲーションを実装する click イベント ハンドラを作成するとします。次のようになります。

document.querySelector('#my-link').addEventListener('click', event => {
    event.preventDefault();
    // ...call history.pushState(), use client-side rendering, etc....
});

カスタム ロジックは、マウスのプライマリ ボタンでトリガーされると意図したとおりに動作するかもしれませんが、中央ボタンがクリックされたときにそのコードが実行されると、実質的に誤検出となります。新しい動作が導入される前は、新しいタブを開くデフォルトの動作が禁止されます。この動作はユーザーの期待に反します。ハンドラの先頭で event.button === 0 を明示的にチェックし、そうである場合にのみコードを実行することもできますが、忘れがちで、その必要があることに気づかないこともよくあります。

必要なコードのみを実行する

誤検出が少なくなる反面、auxclick コールバックは、実際にはプライマリ以外のマウスボタンがクリックされた場合にのみ実行されます。たとえば、新しいタブを開く前に適切なリンク先 URL を計算する必要があるコードがある場合は、auxclick をリッスンして、そのロジックをコールバックに含めることができます。メインのマウスボタンがクリックされたときに実行のオーバーヘッドは発生しません。

ブラウザのサポートと互換性

現在、この新しい動作は Chrome 55 にのみ実装されています。最初の提案で説明したように、ウェブ デベロッパー コミュニティからのフィードバック(肯定的と否定的の両方)は高く評価されています。標準化プロセスに携わっている人たちにフィードバックを共有する最良の方法は、GitHub の問題を提出することです。

それまでの間、デベロッパーは auxclick が広く利用されるのを待つことなく、マウスイベント処理のベスト プラクティスを実施できます。click イベント ハンドラの開始時に MouseEvent.button プロパティの値を確認することで、適切な措置を講じることができます。次のパターンでは、auxclick がネイティブにサポートされているかどうかにかかわらず、メインクリックと補助クリックの処理が異なります。

function handlePrimaryClick(event) {
    // ...code to handle the primary button click...
}

function handleAuxClick(event) {
    // ...code to handle the auxiliary button click….
}

document.querySelector('#my-link').addEventListener('click', event => {
    if (event.button === 0) {
    return handlePrimaryClick(event);
    }


    // This provides fallback behavior in browsers without auxclick.
    return handleAuxClick(event);
});

// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);