矢印キーでフォーカス移動!JavaScript初心者でもできる10の使い方

矢印キーでフォーカスを移動させるJavaScriptのサンプルコードJS
この記事は約21分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、JavaScript初心者でも矢印キーを使ってフォーカスを移動させる方法をマスターできるようになります。

●環境の構築

まずは、JavaScriptを実行するための環境を整えましょう。

次の手順で環境を構築できます。

  1. テキストエディタをインストール(Visual Studio CodeやSublime Textなど)
  2. HTMLファイルを作成し、JavaScriptコードを記述するためのscriptタグを追加

●基本的なフォーカス移動の方法

ここでは、矢印キーでフォーカスを移動させる基本的な方法を紹介します。

○サンプルコード1:矢印キーでフォーカス移動

下記のサンプルコードでは、矢印キーを使って、入力フォーム間でフォーカスを移動できるようになります。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>矢印キーでフォーカス移動</title>
</head>
<body>
  <input type="text" id="input1">
  <input type="text" id="input2">
  <input type="text" id="input3">

  <script>
    document.addEventListener('keydown', function(event) {
      let target = event.target;
      let next = null;

      // 矢印キーの判定
      if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
        next = target.nextElementSibling;
      } else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
        next = target.previousElementSibling;
      }

      // フォーカスを移動
      if (next && next.tagName === 'INPUT') {
        next.focus();
        event.preventDefault();
      }
    });
  </script>
</body>
</html>

このサンプルコードでは、keydownイベントを使って、矢印キーが押されたときにフォーカスを移動させています。

矢印キーの判定はevent.keyを使って行っています。

●応用例

続いて、矢印キーでフォーカスを移動させる応用例を紹介します。

○サンプルコード2:フォーム内でのフォーカス移動

下記のサンプルコードでは、フォーム内で矢印キーを使って、フォーカスを移動できるようになります。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>フォーム内でのフォーカス移動</title>
</head>
<body>
  <form id="form1">
    <input type="text" id="input1">
    <input type="text" id="input2">
    <input type="text" id="input3">
  </form>

  <script>
    document.getElementById('form1').addEventListener('keydown', function(event) {
      let target = event.target;
      let next = null;

      // 矢印キーの判定
      if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
        next = target.nextElementSibling;
      } else if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
        next = target.previousElementSibling;
      }

      // フォーカスを移動
      if (next && next.tagName === 'INPUT') {
        next.focus();
        event.preventDefault();
      }
    });
  </script>
</body>
</html>

このサンプルコードでは、サンプルコード1と同様に矢印キーでフォーカスを移動しますが、今回はフォーム内の入力要素に限定しています。keydownイベントをフォーム要素に設定しています。

○サンプルコード3:テーブル内でのフォーカス移動

テーブル内のセルを矢印キーでフォーカス移動できるようにするサンプルコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>テーブル内でのフォーカス移動</title>
  <style>
    td:focus {
      outline: 2px solid #0000FF;
    }
  </style>
</head>
<body>
  <table id="table1">
    <tr>
      <td tabindex="0">A1</td>
      <td tabindex="0">A2</td>
    </tr>
    <tr>
      <td tabindex="0">B1</td>
      <td tabindex="0">B2</td>
    </tr>
  </table>

  <script>
    // テーブルにkeydownイベントを設定
    document.getElementById('table1').addEventListener('keydown', function(event) {
      let target = event.target;
      let next = null;

      // 矢印キーの判定とフォーカス移動先の取得
      if (event.key === 'ArrowDown') {
        next = target.parentElement.nextElementSibling?.children[target.cellIndex];
      } else if (event.key === 'ArrowRight') {
        next = target.nextElementSibling;
      } else if (event.key === 'ArrowUp') {
        next = target.parentElement.previousElementSibling?.children[target.cellIndex];
      } else if (event.key === 'ArrowLeft') {
        next = target.previousElementSibling;
      }

      // フォーカスを移動
      if (next && next.tagName === 'TD') {
        next.focus();
        event.preventDefault();
      }
    });
  </script>
</body>
</html>

このサンプルコードでは、テーブル内のセルを矢印キーでフォーカス移動できるようにしています。

keydownイベントをテーブル要素に設定し、矢印キーの判定とフォーカス移動先の取得を行っています。

○サンプルコード4:リスト内でのフォーカス移動

リスト内のアイテムを矢印キーでフォーカス移動できるようにするサンプルコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>リスト内でのフォーカス移動</title>
  <style>
    li:focus {
      outline: 2px solid #0000FF;
    }
  </style>
</head>
<body>
  <ul id="list1">
    <li tabindex="0">アイテム1</li>
    <li tabindex="0">アイテム2</li>
    <li tabindex="0">アイテム3</li>
  </ul>

  <script>
    // リストにkeydownイベントを設定
    document.getElementById('list1').addEventListener('keydown', function(event) {
      let target = event.target;
      let next = null;

      // 矢印キーの判定とフォーカス移動先の取得
      if (event.key === 'ArrowDown') {
        next = target.nextElementSibling;
      } else if (event.key === 'ArrowUp') {
        next = target.previousElementSibling;
      }

      // フォーカスを移動
      if (next && next.tagName === 'LI') {
        next.focus();
        event.preventDefault();
      }
    });
  </script>
</body>
</html>

このサンプルコードでは、リスト内のアイテムを矢印キーでフォーカス移動できるようにしています。

リスト要素にkeydownイベントを設定し、矢印キーの判定とフォーカス移動先の取得を行っています。

○サンプルコード5:タブでのフォーカス移動

タブ機能を持つコンテンツで、矢印キーでタブの切り替えができるようにするサンプルコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>タブでのフォーカス移動</title>
  <style>
    .tab:focus {
      outline: 2px solid #0000FF;
    }
    .tabcontent {
      display: none;
    }
    .tabcontent.active {
      display: block;
    }
  </style>
</head>
<body>
  <div>
    <button class="tab" tabindex="0">タブ1</button>
    <button class="tab" tabindex="0">タブ2</button>
    <button class="tab" tabindex="0">タブ3</button>
  </div>
  <div>
    <div class="tabcontent">タブ1の内容</div>
    <div class="tabcontent">タブ2の内容</div>
    <div class="tabcontent">タブ3の内容</div>
  </div>

  <script>
    const tabs = document.querySelectorAll('.tab');
    const tabContents = document.querySelectorAll('.tabcontent');

    // タブにkeydownイベントを設定
    tabs.forEach(tab => {
      tab.addEventListener('keydown', function(event) {
        let target = event.target;
        let next = null;

        // 矢印キーの判定とフォーカス移動先の取得
        if (event.key === 'ArrowRight') {
          next = target.nextElementSibling;
        } else if (event.key === 'ArrowLeft') {
          next = target.previousElementSibling;
        }

        // フォーカスを移動し、タブの内容を切り替える
        if (next && next.classList.contains('tab')) {
          next.focus();
          changeTabContent(next);
          event.preventDefault();
        }
      });
    });

    // タブの内容を切り替える関数
    function changeTabContent(activeTab) {
      tabs.forEach((tab, index) => {
        if (tab === activeTab) {
          tabContents[index].classList.add('active');
        } else {
          tabContents[index].classList.remove('active');
        }
      });
    }

    // 初期状態の設定
    tabs[0].focus();
    changeTabContent(tabs[0]);
  </script>
</body>
</html>

このサンプルコードでは、矢印キーでタブの切り替えができるようにしています。

タブ要素にkeydownイベントを設定し、矢印キーの判定とフォーカス移動先の取得を行っています。

フォーカスが移動したタブに対応するコンテンツを表示するように切り替えています。

○サンプルコード6:カスタムキーでのフォーカス移動

特定のカスタムキーでフォーカス移動ができるようにするサンプルコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>カスタムキーでのフォーカス移動</title>
  <style>
    input:focus {
      outline: 2px solid #0000FF;
    }
  </style>
</head>
<body>
  <form>
    <input type="text" id="input1" tabindex="0">
    <input type="text" id="input2" tabindex="0">
    <input type="text" id="input3" tabindex="0">
  </form>

  <script>
    // カスタムキーとして設定するキーコード
    const customKeyCode = 83; // Sキー

    // 全てのinput要素を取得
    const inputs = document.querySelectorAll('input');

    // input要素にkeydownイベントを設定
    inputs.forEach(input => {
      input.addEventListener('keydown', function(event) {
        if (event.keyCode === customKeyCode) {
          moveFocus(event.target, inputs);
          event.preventDefault();
        }
      });
    });

    // フォーカスを次の要素に移動する関数
    function moveFocus(current, elements) {
      for (let i = 0; i < elements.length; i++) {
        if (elements[i] === current) {
          if (i < elements.length - 1) {
            elements[i + 1].focus();
          } else {
            elements[0].focus();
          }
          break;
        }
      }
    }
  </script>
</body>
</html>

このサンプルコードでは、カスタムキーとして「S」キーを設定しています。

input要素にkeydownイベントを設定し、カスタムキーが押された場合、次の要素にフォーカスを移動します。

フォーカスが最後の要素にある場合、最初の要素に戻ります。

○サンプルコード7:動的コンテンツでのフォーカス移動

動的に生成されたコンテンツでフォーカスを移動させるサンプルコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>動的コンテンツでのフォーカス移動</title>
  <style>
    button:focus {
      outline: 2px solid #0000FF;
    }
  </style>
</head>
<body>
  <div id="content"></div>

  <script>
    // ボタンを動的に生成する関数
    function createButtons() {
      for (let i = 0; i < 5; i++) {
        const button = document.createElement('button');
        button.textContent = 'ボタン' + (i + 1);
        button.addEventListener('keydown', moveFocus);
        document.getElementById('content').appendChild(button);
      }
    }

    // フォーカスを次の要素に移動する関数
    function moveFocus(event) {
      if (event.keyCode === 39 || event.keyCode === 40) { // 右矢印キーまたは下矢印キー
        const next = event.target.nextElementSibling;
        if (next) {
          next.focus();
        } else {
          event.target.parentNode.firstElementChild.focus();
        }
        event.preventDefault();
      } else if (event.keyCode === 37 || event.keyCode === 38) { // 左矢印キーまたは上矢印キー
        const prev = event.target.previousElementSibling;
        if (prev) {
          prev.focus();
        } else {
          event.target.parentNode.lastElementChild.focus();
        }
        event.preventDefault();
      }
    }

    // ボタンを生成
    createButtons();
  </script>
</body>
</html>

このサンプルコードでは、動的に生成されたボタンでフォーカスを移動できるようにしています。

ボタンが生成される際に、それぞれのボタンにkeydownイベントを追加しています。

矢印キーが押された場合、フォーカスを次または前のボタンに移動します。

○サンプルコード8:フォーカス移動のアニメーション

このサンプルコードでは、フォーカス移動時にアニメーションを適用する方法を紹介します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>フォーカス移動のアニメーション</title>
  <style>
    button:focus {
      outline: none;
      transform: scale(1.1);
      transition: transform 0.2s ease-out;
    }
  </style>
</head>
<body>
  <button>ボタン1</button>
  <button>ボタン2</button>
  <button>ボタン3</button>
  <button>ボタン4</button>
  <button>ボタン5</button>
</body>
</html>

このサンプルコードでは、CSSを使用してフォーカスが当たったボタンにアニメーション効果を適用しています。

:focus疑似クラスを使用し、ボタンにフォーカスが当たったときにtransformプロパティでスケーリング効果を適用し、transitionプロパティでアニメーション効果を設定しています。

○サンプルコード9:フォーカス移動の制限

このサンプルコードでは、特定の要素にフォーカスが移動しないように制限する方法を紹介します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>フォーカス移動の制限</title>
</head>
<body>
  <button>ボタン1</button>
  <button>ボタン2</button>
  <button tabindex="-1">ボタン3</button>
  <button>ボタン4</button>
  <button>ボタン5</button>
</body>
</html>

このサンプルコードでは、tabindex属性を使ってフォーカス移動の制限を行っています。

tabindex属性に-1を設定することで、その要素はフォーカスが移動しないようになります。

ここでは、ボタン3にtabindex="-1"を設定しているため、フォーカスが当たらないようになっています。

○サンプルコード10:フォーカス移動のカスタマイズ

このサンプルコードでは、フォーカス移動の順序をカスタマイズする方法を示します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>フォーカス移動のカスタマイズ</title>
</head>
<body>
  <button tabindex="3">ボタン1</button>
  <button tabindex="1">ボタン2</button>
  <button tabindex="4">ボタン3</button>
  <button tabindex="2">ボタン4</button>
  <button tabindex="5">ボタン5</button>
</body>
</html>

このサンプルコードでは、tabindex属性を使ってフォーカス移動の順序をカスタマイズしています。

tabindex属性に正の整数を設定することで、その要素のフォーカス移動の順序を制御できます。

ここでは、それぞれのボタンに異なるtabindex値を設定して、フォーカス移動の順序をカスタマイズしています。

●注意点と対処法

  1. tabindex属性を過度に使用すると、フォーカス移動が直感的でなくなることがあります。
    必要な場合にのみ使用しましょう。
  2. tabindex属性に同じ値を設定した場合、その要素のフォーカス移動順序は定義されていないため、ブラウザによって異なる動作が発生する可能性があります。
    重複しないように注意しましょう。

まとめ

フォーカス移動は、ウェブアプリケーションのアクセシビリティや利便性を向上させるために重要な要素です。

適切なフォーカス管理を行うことで、より使いやすいウェブアプリケーションを作成できます。

ただし、tabindex属性を過度に使用すると、フォーカス移動が直感的でなくなることがあるため、注意して使用しましょう。