在jQuery中查找“next”表单输入元素的最佳方法是什么?

时间:2008-11-14 15:57:50

标签: javascript jquery

使用jQuery,从任意元素开始,在页面上查找下一个表单元素的最佳方法是什么?当我说表单元素时,我的意思是<input><select><button><textarea>

在以下示例中,id为“this”的元素是任意起始点,id为“next”的元素是我想要查找的元素。所有例子都应该使用相同的答案。

示例1:

<ul>
 <li><input type="text" /></li>
 <li><input id="this" type="text" /></li>
</ul>

<ul>
 <li><input id="next" type="text" /></li>
</ul>

<button></button>

示例2:

<ul>
 <li><input id="this" type="text" /></li>
</ul>

<button id="next"></button>

示例3:

<input id="this" type="text" />
<input id="next" type="text" />

示例4:

<div>
  <input id="this" type="text" />
  <input type="hidden" />
  <div>
    <table>
      <tr><td></td><td><input id="next" type="text" /></td></tr>
    </table>
  </div>
  <button></button>
</div>

编辑:到目前为止提供的两个答案都需要为页面上的所有输入元素写一个序列号。正如我在其中一个人的评论中提到的,这是我已经在做的事情,我更喜欢有一个只读解决方案,因为这将发生在一个插件中。

12 个答案:

答案 0 :(得分:52)

荣誉,

如何使用.index?

例如$(':input:eq(' + ($(':input').index(this) + 1) + ')');

答案 1 :(得分:13)

redsquare是绝对正确的,也是一个很好的解决方案,我也在我的一个项目中使用过。

我只是想指出他缺少一些括号,因为当前的解决方案将索引连接到1,而不是将它们加在一起。

因此纠正后的解决方案如下:

$(":input:eq(" + ($(":input").index(this) + 1) + ")");

对于双重帖子感到抱歉,但我找不到评论他的帖子的方法......

答案 2 :(得分:10)

此解决方案不需要索引,也可以与tabindex很好地配合使用 - 换句话说,它为您提供浏览器每次都会在标签上提供的确切元素,而无需任何额外的工作。

function nextOnTabIndex(element) {
      var fields = $($('form')
                    .find('a[href], button, input, select, textarea')
                    .filter(':visible').filter('a, :enabled')
                    .toArray()
                    .sort(function(a, b) {
                      return ((a.tabIndex > 0) ? a.tabIndex : 1000) - ((b.tabIndex > 0) ? b.tabIndex : 1000);
                    }));


      return fields.eq((fields.index(element) + 1) % fields.length);
    }

它的工作原理是抓取表单中的所有可列表字段(由http://www.w3.org/TR/html5/editing.html#focus-management允许),然后根据(http://www.w3.org/TR/html5/editing.html#sequential-focus-navigation-and-the-tabindex-attribute)对字段进行排序,以计算要选项卡的下一个元素。一旦有了,它会查看传入字段在该数组中的位置,并返回下一个元素。

有几点需要注意:

  • jQuery似乎支持jQuery对象上的sort(),但我找不到 它明确地在文档中,因此调用toArray()然后 在jQuery对象中重新包装数组。
  • 还有其他领域 标签可以,但我把它们排除在外,因为它们不标准 表格领域。

我用来测试它的代码是(使用jQuery 1.7):

<script>
  $(function() {
    $('a[href], button, input, select, textarea').click(function() {
      console.log(nextOnTabIndex($(this)).attr('name'));
    })
  });
</script>

<form>
  <input type='text' name='a'/>
  <input type='text' name='b' tabindex='1' />
  <a>Hello</a>
  <input type='text' name='c'/>
  <textarea name='d' tabindex='2'></textarea>
  <input id='submit' type='submit' name='e' tabindex='1' />
</form>

答案 3 :(得分:7)

在尝试了我能找到的每个代码(并且浏览器之间存在问题)之后,我找到了一个适用于顶级浏览器的代码。由于一些奇怪的问题,无法使用以前的例程。

$(document.body).keydown(function(event) {
    if(event.keyCode == 13 ) {
        $(":input")[$(":input").index(document.activeElement) + 1].focus();
        return false;
    }
});

希望这有助于其他人。享受。

答案 4 :(得分:2)

您可以为每个表单项指定一个id(或唯一的类名),将其标识为表单元素,并为其指定索引。例如:

<div>
    <input id="FormElement_0" type="text" />
    <input id="FormElement_1" type="text" />
<div>

然后,如果你想从第一个元素遍历到第二个元素,你可以这样做:

//I'm assuming "this" is referring to the first input

//grab the id
var id = $(this).attr('id');

//get the index from the id and increment it
var index = parseInt(id.split('_')[0], 10);
index++;

//grab the element witht that index
var next = $('#FormElement_' + index);

这样做的好处是,无论位置或类型如何,您都可以将任何元素标记为下一个元素。您还可以控制遍历的顺序。因此,如果出于任何原因你想跳过一个元素并稍后再回过头来,你也可以这样做。

答案 5 :(得分:2)

您可以执行此操作以获取您要查找的表单元素的完整列表:

var yourFormFields = $("yourForm").find('button,input,textarea,select');

然后,应该很容易找到下一个元素:

var index = yourFormFields.index( this ); // the index of your current element in the list. if the current element is not in the list, index = -1

if ( index > -1 && ( index + 1 ) < yourFormFields.length ) { 

                    var nextElement = yourFormFields.eq( index + 1 );

                    }

答案 6 :(得分:1)

或者你可以使用html属性'tabindex',当用户在表单周围选中时,它会转到tabindex =“i”到tabindex =“i + 1”。您可以使用jQuery轻松获取属性。如果没有启用JavaScript,也可以很好地回退给用户。

答案 7 :(得分:1)

我想出了一个在没有明确定义索引的情况下完成工作的函数:

function nextInput(form, id) {
    var aInputs = $('#' + form).find(':input[type!=hidden]');
    for (var i in aInputs) {
        if ($(aInputs[i]).attr('id') == id) {
            if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
                return aInputs[parseInt(i) + 1];
            }
        }
    }
}

这是一个有效的例子。表单标签是为了保持一致性。你真正需要的只是一个普通的父母,甚至可以只使用body标签作为父母(稍微修改一下这个功能)。

将其粘贴到文件中并使用firefox / firebug打开,您将看到它为您的所有示例返回正确的元素:

<html>
  <head>
    <script src="http://www.google.com/jsapi"></script>
    <script>
      function nextInput(form, id) {
        var aInputs = $('#' + form).find(':input[type!=hidden]');
        for (var i in aInputs) {
          if ($(aInputs[i]).attr('id') == id) {
            if (typeof(aInputs[parseInt(i) + 1]) != 'undefined') {
              return aInputs[parseInt(i) + 1];
            }
          }
        }
      }

      google.load("jquery", "1.2.6");
      google.setOnLoadCallback(function() {
        console.log(nextInput('myform1', 'this1'));
        console.log(nextInput('myform2', 'this2'));
        console.log(nextInput('myform3', 'this3'));
        console.log(nextInput('myform4', 'this4'));
      });
    </script>
  </head>
  <body>
    <form id="myform1">
      <ul>
         <li><input type="text" /></li>
         <li><input id="this1" type="text" /></li>
      </ul>
      <ul>
        <li><input id="next1" type="text" /></li>
      </ul>
    </form>

    <form id="myform2">
      <ul>
         <li><input type="text" /></li>
         <li><input id="this2" type="text" /></li>
      </ul>
      <ul>
        <li><input id="next2" type="text" /></li>
      </ul>
    </form>

    <form id="myform3">
      <input id="this3" type="text" />
      <input id="next3" type="text" />
    </form>

    <form id="myform4">
      <div>
        <input id="this4" type="text" />
        <input type="hidden" />
        <div>
        <table>
          <tr><td></td><td><input id="next4" type="text" /></td></tr>
        </table>
        </div>
        <button></button>
      </div>
    </form>
  </body>
</html>

答案 8 :(得分:0)

您可以使用jQuery字段插件来执行此操作。

答案 9 :(得分:0)

var elementSelector = "input:visible,textarea:visible";
var nextSibling = $(elementSelector )[$(elementSelector ).index() + 1];
//$(nextSibling).focus(); possible action

我认为上面的解决方案更简单,或者如果你愿意,你可以将它们全部添加到一行: - )

var nextSibling = $("input:visible,textarea:visible")[$("input:visible,textarea:visible").index() + 1];

答案 10 :(得分:0)

这对我来说很有效,它正确地跳过隐藏的输入:

input_el.nextAll( 'input:visible:first' ).focus();

答案 11 :(得分:0)

使用index(或nextAll)的所有解决方案仅适用于所有表单输入都是兄弟节点的情况,例如:在同一<div>块内。以下内容通过在页面上创建所有可见的非读取输入的id数组并在当前控件之后选出第一个,如果当前控件是页面上的最后一个,则回绕。

ids = $(":input:visible:not([readonly])").map(function () { return this.id });
nextId = ids[($.inArray($(this).attr("id"), ids) + 1) % ids.length];
$("#" + nextId).focus();

使用map函数使其比涉及迭代器的解决方案更简洁。