【JavaScript】focusin / focusout – 要素がフォーカスを受け取った・失ったときに発生するイベント

JavaScriptのfocusinfocusoutは、要素がフォーカスを受け取ったとき、またはフォーカスを失ったときに発生するイベントです。これらのイベントはfocusblurに似ていますが、重要な違いがあります。今回は、それぞれのイベントの基本的な使い方、注意点についてまとめていきたいと思います。

focusin / focusoutイベントとは?

focusinイベント

focusinイベントは、要素がフォーカスを得たときに発生します。このイベントはバブリング(伝播)するため、親要素でもハンドリングできます。

  • フォーム全体でのフォーカス移動の検知。
  • フォーカスが当たった要素に応じてスタイルを変更する。
  • フォーカスされた要素に関する追加情報を表示する。

focusoutイベント

focusoutイベントは、要素がフォーカスを失ったときに発生します。こちらもバブリングする特性があるため、フォームやコンテナ全体で一括してハンドリングできます。

  • フォーカスが外れた際の入力内容の検証。
  • 必要に応じてガイドやエラーメッセージを非表示にする。

基本的な使い方

以下は、focusinfocusoutイベントを使用した簡単な例です。

See the Pen focusin() / focusout() by tones (@tonescodedesign) on CodePen.

JavaScript
const form = document.getElementById('form');

form.addEventListener('focusin', (event) => {
  event.target.classList.add('highlight');
});

form.addEventListener('focusout', (event) => {
  event.target.classList.remove('highlight');
});
HTML
 <form id="form">
  <label for="username">ユーザー名:</label>
  <input type="text" id="username" name="username">
  <br><br>
  <label for="email">メールアドレス:</label>
  <input type="email" id="email" name="email">
</form>

この例では、フォーム内の要素がフォーカスされたときに背景色が変わり、フォーカスが外れると元に戻ります。

入力検証

以下は、focusoutイベントを使用して入力内容を検証する例です。

See the Pen focusin() / focusout() by tones (@tonescodedesign) on CodePen.

JavaScript
const emailInput = document.getElementById('email');
const errorMessage = document.getElementById('error-message');

emailInput.addEventListener('focusout', () => {
  const email = emailInput.value;
  if (!email.includes('@')) {
    errorMessage.textContent = '有効なメールアドレスを入力してください。';
  } else {
    errorMessage.textContent = '';
  }
});
HTML
<form>
  <label for="email">メールアドレス:</label>
  <input type="email" id="email" name="email">
  <div class="error" id="error-message"></div>
</form>
CSS
.error {
  color: red;
  font-size: 12px;
}

このコードでは、メールアドレスの入力欄からフォーカスが外れたときに、入力内容を検証します。

使用時の注意点

focusblurとの違い

  • focusinfocusoutはバブリングするため、親要素で一括してイベントを処理できます。
  • 一方で、focusblurはバブリングしないため、個別の要素にイベントリスナーを追加する必要があります。

効率的なイベント管理

複数の要素に対してfocusblurを使用するとコードが冗長になる場合がありますが、focusinfocusoutを利用すれば親要素でまとめて処理できるため、コードを簡潔に保てます。

アクセシビリティの配慮

  • フォーカス時に表示されるガイドやヘルプは、視覚的な変化だけでなくスクリーンリーダーでも認識可能にする必要があります。
  • 必要に応じてaria-live属性や適切なroleを使用して、補助技術ユーザーにも情報が伝わるようにしましょう。
HTML
<div id="help" aria-live="polite">フォーカスされたときの説明をここに表示します。</div>