表格中存在enabled、disabled输入框,并且需要根据方向键移动光标定位到对应的输入框,同行或者同列时,光标能够循环
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.js"></script>
<title>Document</title>
<style>
table, tr, th, td {
border: 1px solid #ccc;
border-spacing: 0;
border-collapse: collapse
}
td {
padding: 10px;
}
input {
max-width: 100px;
}
</style>
</head>
<body>
<table onkeydown="mouseKeydown(this,event)">
<thead>
<tr>
<th>产品名称</th>
<th>产品号</th>
<th>颜色</th>
<th>缸号</th>
<th>米数</th>
<th>卷数</th>
<th>单价</th>
<th>仓库</th>
<th>总金额</th>
<th>折扣</th>
<th>折后金额</th>
<th>进货单价</th>
<th>预计利润</th>
</tr>
</thead>
<tbody>
<tr index="1" class="">
<input type="hidden" name="detail[1][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[1][product_id]" value="" class="w160">
<input type="text" name="temp[1][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left">
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[1][color_id]" value="">
<input type="text" name="color_name" value="" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[1][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[1][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[1][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[1][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[1][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td class="t_right" style="">
<input type="text" name="detail[1][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[1][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
<tr index="2" class="">
<input type="hidden" name="detail[2][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[2][product_id]" value="" class="w160">
<input type="text" name="temp[2][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left">
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[2][color_id]" value="">
<input type="text" name="color_name" value="" where="" jqac="true" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[2][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[2][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[2][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[2][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[2][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" jqac="" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td class="t_right" style="">
<input type="text" name="detail[2][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[2][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
<tr index="3" class="">
<input type="hidden" name="detail[3][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[3][product_id]" value="" class="w160">
<input type="text" name="temp[3][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left">
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[3][color_id]" value="">
<input type="text" name="color_name" value="" where="" jqac="true" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[3][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[3][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[3][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[3][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[3][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" jqac="" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td class="t_right" style="">
<input type="text" name="detail[3][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[3][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
<tr index="4" class="">
<input type="hidden" name="detail[4][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[4][product_id]" value="" jqproc="" class="w160">
<input type="text" name="temp[4][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left" >
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[4][color_id]" value="">
<input type="text" name="color_name" value="" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[4][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[4][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[4][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[4][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[4][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td width="46" class="t_right" style="">
<input type="text" name="detail[4][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[4][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
<tr index="4" class="">
<input type="hidden" name="detail[4][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[4][product_id]" value="" jqproc="" class="w160">
<input type="text" name="temp[4][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left" >
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" >
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[4][color_id]" value="">
<input type="text" name="color_name" value="" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[4][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[4][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[4][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[4][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[4][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td width="46" class="t_right" style="">
<input type="text" name="detail[4][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[4][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
<tr index="5" class="">
<input type="hidden" name="detail[5][id]" value="">
<td class="t_left" style="">
<input type="hidden" name="detail[5][product_id]" value="" class="w160">
<input type="text" name="temp[5][product_no]" value="" class="w160 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td class="t_left" >
<span style="display:none;"></span>
<input type="hidden" name="detail[1][product_name_id]" value="" class="w120">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off" disabled>
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<input name="temp[1][product_name]" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
<span style="display:none;"></span>
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[5][color_id]" value="">
<input type="text" name="color_name" value="" class="ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td style="white-space:normal;word-wrap: break-word;word-break: break-all;">
<input type="hidden" name="detail[5][size_id]" value="">
<input type="text" name="size_name" value="" class="w120 ac_input detail_input ui-autocomplete-input" autocomplete="off">
</td>
<td tfoot_id="total_quantity" class="t_right" style="">
<input type="text" name="detail[5][quantity]" class="w50" value="" row_total="">
</td>
<td tfoot_id="total_volume" class="t_right" style="">
<input type="text" name="detail[5][volume]" value="">
</td>
<td class="t_right" style="">
<input type="text" name="detail[5][price]" value="" row_total_money="" class="w50">
</td>
<td class="t_left" style="">
<input type="hidden" name="detail[5][warehouse_id]" value="1">
<input type="text" class="w100 ac_input detail_input ui-autocomplete-input" name="warehouse_name" autocomplete="off">
</td>
<td total_row_money="" class="t_right" style=""></td>
<td class="t_right" style="">
<input type="text" name="detail[5][discount]" class="w40" value="" row_total_disount="">
</td>
<td tfoot_id="total_after_discount_money" total_row_dis_money="" class="t_right" style=""></td>
<td class="t_right operate" style="">
<input type="text" name="detail[5][purchase_fee]" value="" class="w50">
</td>
<td class="t_right operate" style=""></td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
</body>
</html>
<script>
function mouseKeydown(obj, event) {
var e = event || window.event;
var keyCode = e.keyCode;
var keyMap = [37, 38, 39, 40];
if ($.inArray(keyCode, keyMap) >= 0) {
var focused = $(obj).find('tbody tr:visible input:focus');
if (focused.length <= 0) {
return;
}
var td_obj = $(focused).parents('td:first');
var td_enabled_inp_length = td_obj.find('input:enabled:not([readonly]):not([type=hidden])').length;
var this_inp_index = td_obj.find('input:enabled:not([readonly]):not([type=hidden])').index(focused);
// 获取当前元素父元素td属性索引
var td_index = td_obj.index();
var tr_obj = td_obj.parents('tr:first');
var tr_visible_gather = $(obj).find('tbody tr:visible');
var tr_index = tr_visible_gather.index(tr_obj);
if (e.keyCode === 40) {//当按下移键触发事件
var next_tr_index = '';
var next_inp_index = '';
$(obj).find('tbody tr:visible:gt('+tr_index+')').each(function (index, item) {
var enabled = $(obj).find('tbody tr:visible').eq($(this).index()).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])');
if (enabled.length >0) {
if(this_inp_index>enabled.length){
next_inp_index = enabled.length - 1;
}else if(this_inp_index === enabled.length){
next_inp_index = this_inp_index - 1;
}else{
next_inp_index = this_inp_index;
}
next_tr_index = $(this).index();
return false;
}
});
if ('' !== next_inp_index) {
$(focused).blur();
$(obj).find('tbody tr:visible').eq(next_tr_index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])').eq(next_inp_index).focus();
}else{
$(obj).find('tbody tr:visible:lt('+tr_index+')').each(function (index, item) {
var enabled = $(obj).find('tbody tr:visible').eq(index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])');
if (enabled.length >0) {
if(this_inp_index>enabled.length){
next_inp_index = enabled.length - 1;
}else if(this_inp_index === enabled.length){
next_inp_index = this_inp_index - 1;
}else{
next_inp_index = this_inp_index;
}
next_tr_index = index;
return false;
}
});
if ('' !== next_inp_index) {
$(focused).blur();
$(obj).find('tbody tr:visible').eq(next_tr_index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])').eq(next_inp_index).focus();
}
}
} else if (e.keyCode === 39) {//当按右移键触发事件
// 获取最近的后一个支持编辑的input元素
var next_inp_index = '';
var next_index = '';
if(td_enabled_inp_length>1){
if(this_inp_index+1 === td_enabled_inp_length){
$(focused).parents('tr:first').children(':gt(' + td_index + ')').each(function (index, item) {
var enabled_length = $(item).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
next_inp_index = $(item).find('input:enabled:not([readonly]):not([type=hidden])').first().index();
next_index = $(item).index();
return false;
}
});
if ('' !== next_inp_index) {
$(focused).blur().parents('tr:first').children().eq(next_index).find('input:enabled:not([readonly]):not([type=hidden]:eq('+next_inp_index+'))').focus();
}
}else{
td_obj.find('input:enabled:not([readonly]):not([type=hidden])').eq(this_inp_index+1).focus();
}
}else{
$(focused).parents('tr:first').children(':gt(' + td_index + ')').each(function (index, item) {
var enabled_length = $(item).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
next_index = $(item).index();
return false;
}
});
if ('' !== next_index) {
$(focused).blur().parents('tr:first').children().eq(next_index).find('input:enabled:not([readonly]):not([type=hidden])').first().focus();
}else{
$(focused).parents('tr:first').children(':lt(' + td_index + ')').each(function (index, item) {
var enabled_length = $(item).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
next_index = $(item).index();
return false;
}
});
if ('' !== next_index) {
$(focused).blur().parents('tr:first').children().eq(next_index).find('input:enabled:not([readonly]):not([type=hidden])').first().focus();
}
}
}
} else if (e.keyCode === 37) {//当按左移键触发事件
// 获取最近的前一个支持编辑的input元素
var prev_index = '';
if(td_enabled_inp_length>1){
if(this_inp_index>0){
td_obj.find('input:enabled:not([readonly]):not([type=hidden])').eq(this_inp_index-1).focus();
}else{
$(focused).parents('tr:first').children(':lt(' + td_index + ')').each(function (index, item) {
// 倒叙获取元素
var enabled_length = tr_obj.children().eq(td_index - 1 - index).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
prev_index = td_index - 1 - index;
return false;
}
});
if ('' !== prev_index) {
$(focused).blur().parents('tr:first').children().eq(prev_index).find('input:enabled:not([readonly]):not([type=hidden])').last().focus();
}
}
}else{
$(focused).parents('tr:first').children(':lt(' + td_index + ')').each(function (index, item) {
// 倒叙获取元素
var enabled_length = tr_obj.children().eq(td_index - 1 - index).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
prev_index = td_index - 1 - index;
return false;
}
});
if ('' !== prev_index) {
$(focused).blur().parents('tr:first').children().eq(prev_index).find('input:enabled:not([readonly]):not([type=hidden])').last().focus();
}else{
tr_obj.children(':gt(' + td_index + ')').each(function (index, item) {
// 倒叙获取元素
var enabled_length = tr_obj.children().eq(tr_obj.children('td:visible').length - 1 - index).find('input:enabled:not([readonly]):not([type=hidden])').length;
if (enabled_length >= 1) {
prev_index = tr_obj.children('td:visible').length - 1 - index
return false;
}
});
if ('' !== prev_index) {
$(focused).blur().parents('tr:first').children().eq(prev_index).find('input:enabled:not([readonly]):not([type=hidden])').last().focus();
}
}
}
} else if (e.keyCode === 38) {//当按上移键触发事件
var next_inp_index = '';
var next_tr_index = '';
var lt_tr_length = $(obj).find('tbody tr:visible:lt('+tr_index+')').length;
$(obj).find('tbody tr:visible:lt('+tr_index+')').each(function (index, item) {
var enabled = $(obj).find('tbody tr:visible').eq(lt_tr_length - 1 - index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])');
if (enabled.length >0) {
if(this_inp_index>enabled.length){
next_inp_index = enabled.length - 1;
}else if(this_inp_index === enabled.length){
next_inp_index = this_inp_index - 1;
}else{
next_inp_index = this_inp_index;
}
next_tr_index = lt_tr_length - 1 - index;
return false;
}
});
if ('' !== next_inp_index) {
$(focused).blur();
$(obj).find('tbody tr:visible:lt('+tr_index+')').eq(next_tr_index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])').eq(next_inp_index).focus();
}else{
var tr_visible_length = tr_obj.siblings('tr:visible:gt('+tr_index+')').length;
tr_obj.siblings('tr:visible:gt('+tr_index+')').each(function (index, item) {
var enabled = $(item).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])');
if (enabled.length >0) {
if(this_inp_index>enabled.length){
next_inp_index = enabled.length - 1;
}else if(this_inp_index === enabled.length){
next_inp_index = this_inp_index - 1;
}else{
next_inp_index = this_inp_index;
}
next_tr_index = tr_visible_length-index-1;
return false;
}
});
if ('' !== next_inp_index) {
$(focused).blur().parents('tr:first').siblings('tr:visible:gt('+tr_index+')').eq(next_tr_index).children().eq(td_index).find('input:enabled:not([readonly]):not([type=hidden])').eq(next_inp_index).focus();
}
}
}
}
}
</script>