Сдвиг фокуса с помощью клавиш со стрелками в JavaScript

Я хочу, чтобы с помощью клавиши со стрелкой можно было перемещаться по всем настраиваемым элементам на моей веб-странице. Поэтому, когда нажата клавиша "вниз", фокус должен перейти к фокусируемому элементу под текущим фокусированным элементом. Вы получаете идею для других клавиш со стрелками, когда нет переключаемого элемента фокусировки, фокус должен оставаться тем же.

Это то, что я получил до сих пор:

$(document).keydown(function(e){    

if (e.keyCode == 37) { //left

   var offset = $("*:focus").offset();

   var allElements = $("#container").find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]');

   var arr = jQuery.makeArray(allElements);

   var topLeft = offset.left
   var minus = topLeft;
   var currentElement = $("*:focus");

   for(var i = 0; i < arr.length; i++)
   {

      if ( (arr[i].offset().left < offset.left)  // This doesn't work for some reason
        && ((offset.left - arr[i].offset().left) < minus))
      {
        currentElement = arr[i];
        minus = offset.left - arr[i].offset().left;
        topLeft = arr[i].offset().left;
      }


      currentElement.focus();
   }


   alert( "left pressed" );
   return false;
}

// Other Keys

});

Идея заключалась в том, чтобы получить все элементы, способные фокусироваться, и выбрать выбрать тот, который подходит для стрелки и фокуса сдвига.

Я не могу заставить этот код работать (он содержит ошибку), и я не уверен, что он даже будет работать.

Thnx заранее

[EDIT]: Я думаю, я был немного расплывчатым. Я не только хочу идти влево и вправо, но и вверх и вниз.

Ответ 1

Я бы сделал намного проще. Просто добавьте общий класс среди объектов, у которых должна быть эта функциональность (f.ex. "move" ) и используйте:

$(document).keydown(
    function(e)
    {    
        if (e.keyCode == 39) {      
            $(".move:focus").next().focus();

        }
        if (e.keyCode == 37) {      
            $(".move:focus").prev().focus();

        }
    }
);
​

См. пример: http://jsfiddle.net/uJ4PJ/

Этот код намного проще и, надеюсь, обладает всеми необходимыми функциями.

Просто убедитесь, что элементы управления находятся в правильном порядке, или это будет работать неправильно.

Ответ 2

Предварительный просмотр - http://jsfiddle.net/FehKh/;)

HTML:

<a href='jqwja' class="focusable">jajaj</a>
<a href='jjaasd' class="focusable focused">jajasdaaj</a>
<a href='jjqwea' class="focusable">jajaacasj</a>
<input value='iddqd' name="DoomII" class="focusable" />​

JS:

// init
$('.focused').focus();

// actual code
$(document).keydown(function(e){    
    if (e.keyCode == 37) { // left
        if($('.focused').prev('.focusable').length)
            $('.focused').removeClass('focused').prev('.focusable').focus().addClass('focused');
    }
    if (e.keyCode == 39) { // right
        if($('.focused').next('.focusable').length)
            $('.focused').removeClass('focused').next('.focusable').focus().addClass('focused');
    }
});​

Ответ 3

После долгих проб и ошибок я разработал этот код, который работает:

function navigate(origin, sens) {
    var inputs = $('#form').find('input:enabled');
    var index = inputs.index(origin);
    index += sens;
    if (index < 0) {
        index = inputs.length - 1;
    }
    if (index > inputs.length - 1) {
        index = 0;
    }
    inputs.eq(index).focus();
}

$('input').keydown(function(e) {
    if (e.keyCode==37) {
        navigate(e.target, -1);
    }
    if (e.keyCode==39) {
        navigate(e.target, 1);
    }
});

стрелка вправо действует как вкладка

стрелка влево действует как вкладка сдвига

Ответ 4

Реализовано выше путем проверки некоторых статей и стека по каналам потока

jQuery.fn.elementAfter = function(other) {
for(i = 0; i < this.length - 1; i++) {
    if (this[i] == other) {
        return jQuery(this[i + 1]);
    }
}
return jQuery;
} ;

jQuery.fn.elementBefore = function(other) {
if (this.length > 0) {               
    for(i = 1; i < this.length; i++) {
        if (this[i] == other) {
            return jQuery(this[i - 1]);
        }
    }
}
return jQuery;
};

https://jsfiddle.net/bkLnq5js/79/

Ответ 5

Это прекрасно работает

$('p').each(function(index) {
  $(this).attr('tabindex', index)
}).on('keyup', function(e) {
  e.preventDefault;
  if (e.keyCode == 39) {
    $('[TabIndex="' + Number(Number($(this).attr('tabindex')) + 1) + '"]').focus();
  }
  if (e.keyCode == 37) {
    $('[TabIndex="' + Number(Number($(this).attr('tabindex')) - 1) + '"]').focus();
  }
});

Ответ 6

Ни одно из вышеперечисленных решений не помогло мне. Этот мой. Это выглядит сложно, но обычно очень просто. Создайте array ссылки и измените фокус, используя массив index. (Мне нужна стрелка вверх/вниз, поэтому коды клавиш разные). Он также работает с добавленными ссылками dynamicly (потому что я нуждался в этом, поэтому я использую on)

$('#links_container').on("keydown", ".link",
    function(e)
    {    

        //start - list of <a>
        var flag = false;
        var smallMeni = document.getElementById('links_container');
        var allElements2 = smallMeni.getElementsByTagName('a'); //.link
        //end

        //start - key down
        if (e.keyCode == 40) 
        {           
            for (var i=0;i<allElements2.length;i++)
            {

                if(flag == true){

                    flag = false

                    allElements2[i].focus();

                    //alert(i)
                }
                else
                {
                    if ( document.activeElement === allElements2[i] )
                    {
                        //alert(i);
                        flag = true;
                    }           
                }

            }
        }
        //end

        //start - key up
        if (e.keyCode == 38) 
        {           
            for (var i=0;i<allElements2.length;i++)
            {

                if ( document.activeElement === allElements2[i] )
                {
                    if (i>0)
                    {
                        allElements2[i-1].focus();                  
                    }
                }           

            }
        }           

        //alert(i);

    }
);