在jQuery中find“下一个”表单input元素的最佳方法?

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

在下面的例子中,id为“this”的元素是任意的起点,id是“next”的元素是我想要find的元素。 同样的答案应该适用于所有的例子。

例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> 

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

荣誉,

怎么使用.index?

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

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

我只想指出他缺less一些括号,因为当前的解决scheme将索引与1连接,而不是将它们相加。

所以更正的解决scheme将如下所示:

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

抱歉的双后,但我找不到方法来评论他的post…

这个解决scheme不需要索引,而且还能和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(),但是我无法在文档中明确地find它,因此调用toArray(),然后在jQuery对象中重新包装数组。
  • 还有其他的字段可以select,但是我把它们放在了外面,因为它们不是标准的表单字段。

我用来testing这个代码(使用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> 

在尝试了所有可以find的代码(并且在浏览器之间存在问题)之后,我发现了一个可以在顶级浏览器中使用的代码。 由于一些奇怪的问题,无法使用以前的例程。

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

希望这可以帮助别人。 请享用。

你可以给每个表单项一个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); 

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

你可以这样做,以获取你正在寻找的表单元素的完整列表:

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

那么,应该很容易find下一个元素:

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

或者你可以使用HTML属性“tabindex”,这是为了当用户在一个表格上标记时,它会到tabindex =“i”到tabindex =“i + 1”。 你可以使用jQuery来很容易的获取属性。 如果没有启用javascript,用户也可以很好地回到用户身上。

我想出了一个没有明确定义索引的function:

 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]; } } } } 

这是一个工作的例子。 表单标签是为了一致性。 所有你真正需要的是一个共同的父母,甚至可以使用身体标签作为父母(稍作修改)。

把它粘贴到一个文件中,用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> 

你可以使用jQuery字段插件,允许你这样做。

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

我只是觉得上面的解决scheme更简单,或者你可以只添加一行,如果你想:-)

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

这对我很好,它正确地跳过隐藏的input:

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

所有使用index(或者nextAll)的解决scheme只能在所有表单input都是同级的情况下工作,例如在同一个<div>块内。 下面通过在页面上创build一个所有可见,非只读input的ID数组,在当前控件之后挑出第一个,如果当前控件是页面上的最后一个控件,则循环。

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

使用map函数比使用迭代器的解决scheme更简洁一些。