Подтвердить что ты не робот

Имитация нажатия клавиши TAB: фокусировка следующего элемента, определяемая `tabIndex`

У меня есть два элемента ввода, первый - сфокусирован, и я хочу сфокусировать второй, моделируя событие нажатия клавиши TAB/keydown. (Примечание: я не хочу использовать .next() или такой.)

Это мой код, вдохновленный этим вопросом:

$('input').first().focus();

var e = $.Event('keydown');

e.which = 9; // TAB
$(':focus').trigger(e);

См. http://jsfiddle.net/3PcPH/

Код не работает. Что не так?

4b9b3361

Ответ 1

Существует простой программный способ сделать это с помощью Javascript... так что здесь грубый способ.

Согласно W3:

Элементы, которые могут получать фокус, должны быть перемещены пользовательскими агентами в соответствии со следующими правилами:

  • Те элементы, которые поддерживают атрибут tabindex и назначают положительное значение для него осуществляется сначала. Навигация исходит от элемент с наименьшим значением tabindex для элемента с наивысшим значением стоимость. Значения не обязательно должны быть последовательными и не должны начинаться с каких-либо особое значение. Элементы, имеющие одинаковые значения tabindex, должны перемещаться в порядке их появления в потоке символов.
  • Те элементы, которые не поддерживают атрибут tabindex или поддерживают его и присвойте ему значение "0". Эти элементы перемещаются в том порядке, в котором они появляются в потоке символов.
  • Элементы которые отключены, не участвуют в порядке табуляции.

Я выполнил это, сохранив порядок элементов в форме, которая имеет tabIndex > 0 в своем порядке tabIndex, а затем конкатенирует остальные элементы в том порядке, в котором они появляются в документе. Следующий код имитирует нажатие клавиши Tab при фокусировке на ввод формы и нажимается буква "z" (но вы можете изменить это на любое условие, которое вам нужно):

$(':input').keypress(function(e){ 

    // if 'z' pressed
    if (e.which == 122) {

        // if we haven't stored the tabbing order
        if (!this.form.tabOrder) {

            var els = this.form.elements,
                ti = [],
                rest = [];

            // store all focusable form elements with tabIndex > 0
            for (var i = 0, il = els.length; i < il; i++) {
                if (els[i].tabIndex > 0 &&
                    !els[i].disabled && 
                    !els[i].hidden && 
                    !els[i].readOnly &&
                    els[i].type !== 'hidden') {
                    ti.push(els[i]);
                }
            }

            // sort them by tabIndex order
            ti.sort(function(a,b){ return a.tabIndex - b.tabIndex; });

            // store the rest of the elements in order
            for (i = 0, il = els.length; i < il; i++) {
                if (els[i].tabIndex == 0 &&
                    !els[i].disabled && 
                    !els[i].hidden && 
                    !els[i].readOnly &&
                    els[i].type !== 'hidden') {
                    rest.push(els[i]);
                }
            }

            // store the full tabbing order
            this.form.tabOrder = ti.concat(rest);
        }

        // find the next element in the tabbing order and focus it
        // if the last element of the form then blur
        // (this can be changed to focus the next <form> if any)
        for (var j = 0, jl = this.form.tabOrder.length; j < jl; j++) {
            if (this === this.form.tabOrder[j]) {
                if (j+1 < jl) {
                    $(this.form.tabOrder[j+1]).focus();
                } else {
                    $(this).blur();
                }
            }
        }

    }

});

Смотрите демонстрацию

Ответ 2

По умолчанию поведение табуляции состоит в том, чтобы просто перейти к следующему элементу формы (в исходном порядке), чтобы вы могли просто перебирать все элементы, которые вам нужны, найти тот, который имеет фокус, и перенести фокус на следующий. У нас есть :input селектор для поиска элементов формы так что-то вроде этого:

var $all = $('form :input');
var focused = $(':focus')[0];
for(var i = 0; i < $all.length - 1; ++i) {
    if($all[i] != focused)
        continue;
    $all[i + 1].focus();
    break;
}
// Must have been focused on the last one or none of them.
if(i == $all.length - 1)
    $all[0].focus();

Демо: http://jsfiddle.net/ambiguous/Avugy/1/

Или вы можете установить атрибуты tabindex и увеличить их с помощью wrap-around:

var next_idx = parseInt($(':focus').attr('tabindex'), 10) + 1;
var $next_input = $('form [tabindex=' + next_idx + ']');
if($next_input.length)
    $next_input.focus();
else
    $('form [tabindex]:first').focus();

Демо: http://jsfiddle.net/ambiguous/k9VpV/

Работа с пробелами в значениях атрибута tabindex остается в виде упражнения.

Ответ 4

Вот решение, использующее jquery для имитации функции TAB с ключом Enter:

https://jsfiddle.net/tuho879j/

$('input').keypress(function(event){
  if(event.which == '13')   //ENTER     
  {
    var tabIndex = $(this).attr('tabIndex');

    var all_inputs = $(this).closest('table').find('input:visible');
    var inputs = all_inputs.filter(function() {
      return $(this).attr("tabIndex") > tabIndex;
    })

    if(inputs.length != 0)
    {
        inputs = $(inputs).sort(function(a,b){
          return $(a).attr('tabIndex')-$(b).attr('tabIndex');
        });
    }
    else
    {
        inputs = $(all_inputs).sort(function(a,b){
          return $(a).attr('tabIndex')-$(b).attr('tabIndex');
        });
    }


    var elem = inputs.eq( inputs.index(this)+ 1 );
    if(elem.length == 0)
        elem = inputs.eq(0);

    elem.focus();
    event.preventDefault();
  }
});

Ответ 5

$('input').first().focus();

var e = $.Event('keydown');

e.which = 9; // TAB
$(':focus').bind('keydown',function(e){
    if(e.which == 9){
        //this.value="tab";
        $('input:eq(1)').focus();
    }
   e.preventDefault(); 
});

вам нужно связать событие "keydown" и настроить свою функцию события.