JavaScript でフォーカスの当たっているボタンなどからフォーカスを外す

ブラウザー上のボタンを押して HTML などでダイアログを描画した場合、ボタンが隠れていたとしてももともと押されたボタンにフォーカスが当たったままになっているため、 Enter キーなどを押すとまたボタンが押されたことになってしまい、イベントが再発してしまいます。

これを防ぐ方法を考えてみます。

対策

Enter キーでボタンの Click イベントが発火するのは、そのボタンにフォーカスが当たっている場合だけです。

ということでボタンが押されたタイミングでフォーカスを外してやれば、この問題は解決します。

対策としては下記の 2 つが考えられます。

  1. 他の要素にフォーカスを移す
  2. アクティブなボタンからフォーカスを外す

1. 他の要素にフォーカスを移す

ダイアログを表示しているということはなんらかのボタンがあるはずなので、ダイアログのボタンにフォーカスを移してしまうというのが一番簡単でしょう。別のボタンにフォーカスが当たれば、もともとクリックされたボタンからは自動的にフォーカスが外れます。

これはダイアログ側のボタンの focus() を呼ぶだけなので簡単です。

dialogButton.focus()

2. アクティブなボタンからフォーカスを外す

ダイアログ側のボタンにもデフォルトでフォーカスしたくない場合など、他にフォーカスを当てるべき要素がない場合も考えられます。この場合は、単にボタンからフォーカスを外すようにします。

sourceButton.blur()

なお、ボタン自体の要素を取得するのが面倒な場合、大抵のブラウザーでアクティブな要素は document.activeElement で取得できるようなので、その blur() を呼べば、フォーカスが外れます。

document.activeElement.blur()

余談ですが、なぜ blur (ぼかす) かというと、 focus (焦点を合わせる) の対義語だからでしょう。日本人からすれば unfocus のほうが直感的な気はしますが、こちらはあまり一般的な動詞ではないからですかね。

Tab でフォーカスできちゃう問題と対策

がんばってフォーカスを外しても、ユーザーが Tab キーを押していけば、もとのボタンに再度フォーカスを当てることができます。これはなんとも防ぎようがありません。

ということで、この対策としては button.disabled = "disabled" とでもして、ボタンを無効化するのが一番でしょう。

ただし、当たり前ですが、無効なままだと一生押せなくなってしまうので、ダイアログが閉じられたあとなどに有効に戻すのをお忘れなく。

クリックされたら無効化して、必要なときに有効に戻すのは面倒ですが、アプリケーションの動作としては重要な部分ですので、がんばって実装しましょう。

kenzauros