7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】TABキーによる要素のフォーカス送りをグループ内でループさせる

Last updated at Posted at 2022-08-27

HTMLタグのtabindex属性が同じ値同士の要素はTABキーによるフォーカス送りが該当要素内で順に行われるので、グループ化したい要素にそれぞれ同じ値のtabindexを振り、それぞれのグループ内での先頭または終端の要素にフォーカスが当たっている際にTABキーまたはSHIFT+TABキーが押下された際には逆側の末端の要素にフォーカスを移動させることで、グループ内でフォーカス移動がループするようにしています。


動作デモ

マウスポインタで適当な要素を選択したあとは、その要素が属するグループ内でTABキーまたはSHIFT+TABキーによるフォーカス移動がループします。

sample.html
<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='utf-8'>
    <title>tabIndexGroup</title>
    <style>
      input[type=text] {
        width: 80px;
      }
    </style>
  </head>
  <body>
    <input type='text' class='group1' placeholder='A'>
    <input type='text' class='group1' placeholder='A'>
    <input type='text' class='group1' placeholder='A'>
    <input type='checkbox' class='group1' placeholder='A'>
    <button class='group1'>A</button><br><br>

    <input type='text' class='group2' placeholder='B'>
    <input type='text' class='group2' placeholder='B'>
    <input type='text' class='group2' placeholder='B'>
    <input type='checkbox' class='group2' placeholder='B'>
    <button class='group2'>B</button><br><br>

    <input type='text' class='group3' placeholder='C'>
    <input type='text' class='group3' placeholder='C'>&emsp;
    <input type='text' class='group4' placeholder='D'>
    <input type='text' class='group4' placeholder='D'><br>

    <input type='text' class='group3' placeholder='C'>
    <input type='text' class='group3' placeholder='C'>&emsp;
    <input type='text' class='group4' placeholder='D'>
    <input type='text' class='group4' placeholder='D'>

    <script>
    'use strict';

    const setTabIndex = cssSelector => {
      const targetElements = document.querySelectorAll(cssSelector);
      const lastIndex = targetElements.length - 1;
      const newTabIndex = Math.max(...[...document.querySelectorAll('*')].map(e => e.tabIndex)) + 1;
      targetElements.forEach(e => e.tabIndex = newTabIndex);

      document.addEventListener('keydown', e => {
        if(e.key !== 'Tab') return;
        if(e.target === targetElements[e.shiftKey ? 0 : lastIndex]) {
          e.preventDefault();
          targetElements[e.shiftKey ? lastIndex : 0].focus();
        }
      });
    };

    setTabIndex('.group1');
    setTabIndex('.group2');
    setTabIndex('.group3');
    setTabIndex('.group4');
    </script>
  </body>
</html>

MDNによると、tabindexの値に0より大きな値を使用することは以下の理由から避けるべきである旨の説明があるので、乱用はしないほうが良いかもしれません。

tabindex | MDN

tabindex の値に 0 よりも大きな値を使用することは避けてください。そうすると、支援技術に頼っている人がページコンテンツを移動したり操作したりすることが難しくなります。代わりに、論理的な順序で要素を並べて文書を書いてください。


7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?