基于jquery实现表格中的上下左右键切换input的焦点

基于jquery实现表格中的上下左右键切换input的焦点,第1张

思路有用,实际无用

前段时间在项目中遇到一个表格中要批量录入非常多的数据,鼠标键盘操作令人眼花缭乱,顿有想法要做个利用键盘的上下左右键切换输入框焦点的小插件。

要实现的功能为:

上键:焦点到上一行相同列的input,

下键:焦点到下一行相同列的input,

左键:焦点到本行左边相邻的input,

右键:焦点到本行右边相邻的input

当然这里说的input都在一个table中的所有的input。既然是要通过键来实现,我只能想到通过keydown的事件来处理了,通过测试,那个几个键的code分别为:

上键:38,下键:40,左键:37,右键:39.当keycode等于这几个值时我就进行处理,这里用switch行,用if,esle也可以,我比较喜欢用后者

比较关键的地方是要找到按键后焦点该去哪个input。 如果利用jquery,首先会想到的就是查找父元素中的符合条件的input的下一个,在同一个tr中这个比较好找,但如果当前元素是本行的最后一个,如果输入右键,焦点应该跳到下一行的第一个inpput,这时候就麻烦了。并且如果单纯的利用dom就那样find来find去,很难达到目的。

上下键的切换只要找到input间相对应的index就可以了。中间本来想通过input所在的单元格的索引来查找查找上行或者下行的同列的单元格中的input,但通过parents查找的td总是与通过tr td中超找的相对应的td不相等,利用chome调试只有选择器有区别,其他属性都一致,可就是用index方法找不出来,始终是-1...此路就此终结

不得不采用终极解决方案:在input上加属性,存储他是第几行第几列,到时直接取出,去找上下行的第几列就得了,所以在遍历的符合条件的input时加上这句

$(this).attr("_r_", inputRowIndex).attr("_c_", j);

inputRowIndex为行的索引,j为列的索引.

现在就要考虑每次要从哪去查找那些input,如果通过jquery的dom去找,每次keydown都去find,效率自然会比较低,为什么低不太好解释。这里显然用变量来存储所有的input会高效些。但又如何实现很方便的查找呢?

比较自然的我就会想到构造一个table那样的立体结构来存储,一行一行的保存,并且都是按顺序的存储,并且我能在每个元素上取到我想要的东西,比如当前元素是第几行,第几列。我能很方便的获取数据,比如我传递第几行,第几列过去就能很方便的获取对应的input。这两样东西js都有现成的了,第一个用json,第二个,嘿嘿,非数组不能那样方便高效的获取数据了,于是我定义出如下数据格式

var rowInputs = [ [ { "length": len, //当前行有多少个input "rowindex":row, //当前行在所有数据行中的索引 “data”:[  //input集合 { "c": j, "input": this } //单个input元素,c为列 。。。。 ]} 。。。。 ] 。。。]; //所有的input集合,一个元素为一个tr中的所有的input

这样我能比较方便的找到当前元素的第几行,第几列,然后根据keycode来计算要获得焦点的input:(查看了排版,源代码还是直接在下面看好了)

见下完整代码$(rowInputs[r].data[c].input).focus();为设置焦点 br br 好了,大概就这么多了吧。 br strong 不过后面还要注意的是,如果要通用到所有的项目中,那么应该考虑隐藏的,只读的情况,那些input都不赢考虑在内 /strong br 经实际测试,有一行数据都是只读的,所有出现那样的情况,应该整行数据都抛弃:var thisRowInputs;if (!inputType) { //所有的input thisRowInputs = $(obj).find("input:not(:disabled):not(:hidden):not([readonly])");} else { thisRowInputs = $(obj).find("input:not(:disabled):not(:hidden):not([readonly])[type=" + inputType + "]");}if (thisRowInputs.length == 0) return true;

完整源代码如下:

var tabTableInput = function (tableId, inputType) { var rowInputs = []; var trs = $("#" + tableId).find("tr"); var inputRowIndex = 0; $.each(trs, function (i, obj) { if ($(obj).find("th").length 0) { //跳过表头 return true; } var rowArray = []; var thisRowInputs; if (!inputType) { //所有的input thisRowInputs = $(obj).find("input:not(:disabled):not(:hidden):not([readonly])"); } else { thisRowInputs = $(obj).find("input:not(:disabled):not(:hidden):not([readonly])[type=" + inputType + "]"); } if (thisRowInputs.length == 0) return true; thisRowInputs.each(function (j) { $(this).attr("_r_", inputRowIndex).attr("_c_", j); rowArray.push({ "c": j, "input": this }); $(this).keydown(function (evt) { var r = $(this).attr("_r_"); var c = $(this).attr("_c_"); var tRow if (evt.which == 38) { //上 if (r == 0) return; r--; //向上一行 tRow = rowInputs[r]; if (c tRow.length - 1) { c = tRow.length - 1; } } else if (evt.which == 40) { //下 if (r == rowInputs.length - 1) { //已经是最后一行 return; } r++; tRow = rowInputs[r]; if (c tRow.length - 1) { c = tRow.length - 1; } } else if (evt.which == 37) { //左 if (r == 0 c == 0) {  //第一行第一个,则不执行操作 return; } if (c == 0) { //某行的第一个,则要跳到上一行的最后一个,此处保证了r大于0 r--; tRow = rowInputs[r]; c = tRow.length - 1; } else { //否则只需向左走一个 c--; } } else if (evt.which == 39) { //右 tRow = rowInputs[r]; if (r == rowInputs.length - 1 c == tRow.length - 1) { //最后一个不执行操作 return; } if (c == tRow.length - 1) { //当前行的最后一个,跳入下一行的第一个 r++; c = 0; } else { c++; } } $(rowInputs[r].data[c].input).focus(); }); }); rowInputs.push({ "length": thisRowInputs.length, "rowindex": inputRowIndex, "data": rowArray }); inputRowIndex++; }); }

调用很简单:

 new tabTableInput("tblGrid","text"); 至于后面那个参数,看下源代码就得了


本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 基于jquery实现表格中的上下左右键切换input的焦点

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情