Navigation using arrow keys

Asked

Viewed 515 times

2

I need to navigate the DOM through the arrow keys. I can accomplish it when it goes only in two directions (up or down, front or back), but to move in the four directions I did not find a way. I need this navigation to take into account only a certain selector, in case the tag '<a>' Ex:

inserir a descrição da imagem aqui

Source:

<body>
    <a href="#">teste</a> <a href="#">TESTE</a> <a href="#">teste</a> <a href="#">TESTE</a><br/>
    <a href="#">teste</a> <a href="#">TESTE</a> <a href="#">teste</a> <a href="#">TESTE</a><br/>
    <a href="#">teste</a> <a href="#">TESTE</a> <a href="#">teste</a> <a href="#">TESTE</a><br/>

    <script>
      $(document).ready(function(){
        $(document).keydown(function(e){
          switch (e.keyCode)
          {
            //esquerda
            case 37:
              var elAtivo    = document.activeElement;
              var elAnterior = $(elAtivo).prevAll('a').first();

              $(elAnterior).focus();
            break;
            //cima
            case 38:
            break;
            //direita
            case 39:
              var elAtivo   = document.activeElement;
              var elProximo = $(elAtivo).nextAll('a').first();
              $(elProximo).focus();
            break;
            //baixo
            case 40:
            break;

          }
        });
      });
    </script>
  </body>
  • You could post the code you have so far?

  • I edited the question to display how the code is currently.

1 answer

0


It is possible to realize picking up the coordinates of the items in question and checking which ones would be closer.

I created a function to pick up the coordinates and implement the movements up and down that were missing in your case.

It would be interesting to adopt the same pattern for all cases, thus regardless of the sequence of items in the HTML, but from its position on the screen.

Follows the code:

<body>
  <a href="#">1</a> <a href="#">2</a> <a href="#">3</a> <a href="#">4</a><br/>
  <a href="#">5</a> <a href="#">6</a> <a href="#">7</a> <a href="#">8</a><br/>
  <a href="#">9</a> <a href="#">10</a> <a href="#">11</a> <a href="#">12</a><br/>

  <script>
    $(document).ready(function () {
      $(document).keydown(function (e) {
        const elAtivo = document.activeElement;
        const as = [].slice.call($('a'));

        switch (e.keyCode) {
          //esquerda
          case 37:
            var elAnterior = $(elAtivo).prevAll('a').first();
            $(elAnterior).focus();
            break;
          //cima
          case 38:
            let elProximoCima;

            as.forEach(el => {
              if (elProximoCima === undefined)
                elProximoCima = el
              if (getOffset(el).top < getOffset(elAtivo).top &&
                getOffset(elAtivo).top - getOffset(el).top <= getOffset(elAtivo).top - getOffset(elProximoCima).top) {
                if (Math.abs(getOffset(el).left - getOffset(elAtivo).left) <=
                  Math.abs(getOffset(elProximoCima).left - getOffset(elAtivo).left))
                  elProximoCima = el
              }
            });

            $(elProximoCima).focus();
            break;
          //direita
          case 39:
            var elProximo = $(elAtivo).nextAll('a').first();
            $(elProximo).focus();
            break;
          //baixo
          case 40:
            let elProximoBaixo;

            as.forEach(el => {
              if (elProximoBaixo === undefined)
                elProximoBaixo = el
                if (getOffset(el).top > getOffset(elAtivo).top &&
                getOffset(el).top - getOffset(elAtivo).top >= getOffset(elProximoBaixo).top - getOffset(elAtivo).top) {
                if (Math.abs(getOffset(el).left - getOffset(elAtivo).left) <=
                  Math.abs(getOffset(elProximoBaixo).left - getOffset(elAtivo).left))
                  elProximoBaixo = el
              }
            });
            $(elProximoBaixo).focus();
            break;

        }
      });
    });

    function getOffset(el) {
      const rect = el.getBoundingClientRect();
      return {
        left: rect.left + window.scrollX,
        top: rect.top + window.scrollY
      };
    }
  </script>
</body>

I also inserted a CSS to make the change more visual:

<style>
    a {
      margin: 30px;
    }

    a:focus {
      color: red;
    }
</style>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.