在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更简洁一些。