模拟TAB keydown:聚焦由tabIndex确定的下一个元素

时间:2022-08-23 22:40:00

I have two input elements, the first is focused, and I want to focus the second by simulating the TAB keypress/keydown event. (Note: I don't want to use .next() or such.)

我有两个输入元素,第一个是聚焦的,我想通过模拟TAB keypress / keydown事件来关注第二个。 (注意:我不想使用.next()等。)

This is my code, inspired from this question:

这是我的代码,灵感来自这个问题:

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

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

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

Please see http://jsfiddle.net/3PcPH/

请参阅http://jsfiddle.net/3PcPH/

The code doesn't work. What is wrong?

代码不起作用。哪里不对?

5 个解决方案

#1


34  

There is no simple programmatic way to do this using Javascript... so here's a brute force way.

使用Javascript没有简单的编程方式来做到这一点...所以这是一种蛮力的方式。

According to W3:

根据W3:

Elements that may receive focus should be navigated by user agents according to the following rules:

应该获得焦点的元素应由用户代理根据以下规则进行导航:

  1. Those elements that support the tabindex attribute and assign a positive value to it are navigated first. Navigation proceeds from the element with the lowest tabindex value to the element with the highest value. Values need not be sequential nor must they begin with any particular value. Elements that have identical tabindex values should be navigated in the order they appear in the character stream.
  2. 首先导航那些支持tabindex属性并为其指定正值的元素。导航从具有最低tabindex值的元素继续到具有最高值的元素。值不必是顺序的,也不必以任何特定值开头。具有相同tabindex值的元素应按它们在字符流中出现的顺序进行导航。
  3. Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.
  4. 接下来导航那些不支持tabindex属性或支持它并为其赋值“0”的元素。这些元素按它们在字符流中出现的顺序进行导航。
  5. Elements that are disabled do not participate in the tabbing order.
  6. 禁用的元素不参与Tab键顺序。

I accomplished this by storing the order of elements in the form that have tabIndex > 0 in their tabIndex order and then concatenating the rest of the elements in the order they appear within the document. The following code simulates a tab keypress when focused on a form input and the letter 'z' is pressed (but you can change this to whatever condition you require):

我通过在tabIndex> 0中以tabIndex> 0顺序存储元素的顺序,然后按照它们在文档中出现的顺序连接其余元素来完成此操作。下面的代码模拟了一个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();
                }
            }
        }

    }

});

See demo

#2


4  

The default tabbing behavior is to just go to the next (in source order) form element so you could just iterate through all the elements you care about, find the one that has focus, and move the focus to the next one. We have the :input selector for finding the form elements so something like this:

默认的Tab键行为是转到下一个(在源顺序中)表单元素,这样您就可以遍历所关注的所有元素,找到具有焦点的元素,并将焦点移动到下一个元素。我们有:输入选择器,用于查找表单元素,如下所示:

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();

Demo: http://jsfiddle.net/ambiguous/Avugy/1/

演示:http://jsfiddle.net/ambiguous/Avugy/1/

Or you could set tabindex attributes and increment them with wrap-around:

或者您可以设置tabindex属性并使用环绕增加它们:

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();

Demo: http://jsfiddle.net/ambiguous/k9VpV/

演示:http://jsfiddle.net/ambiguous/k9VpV/

Dealing with gaps in the tabindex attribute values is left as an exercise.

处理tabindex属性值中的间隙是一项练习。

#3


0  

Try this sample out http://jsfiddle.net/mporras/3jXQQ/18/embedded/result/

试试这个样本http://jsfiddle.net/mporras/3jXQQ/18/embedded/result/

#4


0  

Here is a solution using jquery to simulate the TAB functionallity with the Enter key:

这是一个使用jquery使用Enter键模拟TAB功能的解决方案:

https://jsfiddle.net/tuho879j/

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


-1  

$('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(); 
});

you need to bind 'keydown' event to and custom your event function.

你需要将'keydown'事件绑定到并自定义你的事件函数。

#1


34  

There is no simple programmatic way to do this using Javascript... so here's a brute force way.

使用Javascript没有简单的编程方式来做到这一点...所以这是一种蛮力的方式。

According to W3:

根据W3:

Elements that may receive focus should be navigated by user agents according to the following rules:

应该获得焦点的元素应由用户代理根据以下规则进行导航:

  1. Those elements that support the tabindex attribute and assign a positive value to it are navigated first. Navigation proceeds from the element with the lowest tabindex value to the element with the highest value. Values need not be sequential nor must they begin with any particular value. Elements that have identical tabindex values should be navigated in the order they appear in the character stream.
  2. 首先导航那些支持tabindex属性并为其指定正值的元素。导航从具有最低tabindex值的元素继续到具有最高值的元素。值不必是顺序的,也不必以任何特定值开头。具有相同tabindex值的元素应按它们在字符流中出现的顺序进行导航。
  3. Those elements that do not support the tabindex attribute or support it and assign it a value of "0" are navigated next. These elements are navigated in the order they appear in the character stream.
  4. 接下来导航那些不支持tabindex属性或支持它并为其赋值“0”的元素。这些元素按它们在字符流中出现的顺序进行导航。
  5. Elements that are disabled do not participate in the tabbing order.
  6. 禁用的元素不参与Tab键顺序。

I accomplished this by storing the order of elements in the form that have tabIndex > 0 in their tabIndex order and then concatenating the rest of the elements in the order they appear within the document. The following code simulates a tab keypress when focused on a form input and the letter 'z' is pressed (but you can change this to whatever condition you require):

我通过在tabIndex> 0中以tabIndex> 0顺序存储元素的顺序,然后按照它们在文档中出现的顺序连接其余元素来完成此操作。下面的代码模拟了一个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();
                }
            }
        }

    }

});

See demo

#2


4  

The default tabbing behavior is to just go to the next (in source order) form element so you could just iterate through all the elements you care about, find the one that has focus, and move the focus to the next one. We have the :input selector for finding the form elements so something like this:

默认的Tab键行为是转到下一个(在源顺序中)表单元素,这样您就可以遍历所关注的所有元素,找到具有焦点的元素,并将焦点移动到下一个元素。我们有:输入选择器,用于查找表单元素,如下所示:

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();

Demo: http://jsfiddle.net/ambiguous/Avugy/1/

演示:http://jsfiddle.net/ambiguous/Avugy/1/

Or you could set tabindex attributes and increment them with wrap-around:

或者您可以设置tabindex属性并使用环绕增加它们:

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();

Demo: http://jsfiddle.net/ambiguous/k9VpV/

演示:http://jsfiddle.net/ambiguous/k9VpV/

Dealing with gaps in the tabindex attribute values is left as an exercise.

处理tabindex属性值中的间隙是一项练习。

#3


0  

Try this sample out http://jsfiddle.net/mporras/3jXQQ/18/embedded/result/

试试这个样本http://jsfiddle.net/mporras/3jXQQ/18/embedded/result/

#4


0  

Here is a solution using jquery to simulate the TAB functionallity with the Enter key:

这是一个使用jquery使用Enter键模拟TAB功能的解决方案:

https://jsfiddle.net/tuho879j/

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


-1  

$('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(); 
});

you need to bind 'keydown' event to and custom your event function.

你需要将'keydown'事件绑定到并自定义你的事件函数。