jQuery 模拟 TAB 键按下:聚焦由 `tabIndex` 确定的下一个元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7303507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:39:56  来源:igfitidea点击:

Simulating the TAB keydown: focusing next element as determined by `tabIndex`

jquery

提问by Randomblue

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?

该代码不起作用。怎么了?

回答by mVChr

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. 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.
  3. Elements that are disabled do not participate in the tabbing order.

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

  1. 那些支持 tabindex 属性并为其分配正值的元素首先被导航。导航从 tabindex 值最低的元素到值最高的元素。值不必是连续的,也不必以任何特定值开头。具有相同 tabindex 值的元素应该按照它们在字符流中出现的顺序进行导航。
  2. 接下来导航那些不支持 tabindex 属性或支持它并为其分配值“0”的元素。这些元素按照它们在字符流中出现的顺序进行导航。
  3. 禁用的元素不参与 Tab 键顺序。

I accomplished this by storing the order of elements in the form that have tabIndex > 0in 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 顺序,然后按照它们在文档中出现的顺序连接其余元素。以下代码在关注表单输入并按下字母“z”时模拟 Tab 键按下(但您可以将其更改为您需要的任何条件):

$(':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

看演示

回答by mu is too short

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 :inputselector for finding the form elements so something like this:

默认的 Tab 行为是只转到下一个(按源顺序)表单元素,这样您就可以遍历您关心的所有元素,找到具有焦点的元素,然后将焦点移到下一个元素。我们有: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();

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

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

Or you could set tabindexattributes 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 tabindexattribute values is left as an exercise.

处理tabindex属性值中的差距留作练习。

回答by burgund

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

回答by iwege

$('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”事件绑定到并自定义您的事件函数。