javascript - 如何将焦点更改为表格单元格中的下一个或上一个可聚焦和启用的输入(仅限 jQuery 或 vanilla javascript)?
问题描述
在 HTML 表格中,合理数量的单元格,跨越多行,包括可能启用或不启用的文本输入,具体取决于下拉列表中先前选择的选项。虽然 tabindex 已正确配置,以便用户可以使用 TAB 或 SHIFT+TAB 在这些输入之间导航,但我被要求使用 LEFT 和 RIGHT 箭头键复制此行为,事实证明这很难实现。
HTML 的简化版本:
<html><body>
<table><tr>
<th></th>
<th>Sample<br/>01</th>
<th>Sample<br/>02</th>
<th>Sample<br/>03</th>
<th>Sample<br/>04</th>
<th>Sample<br/>05</th>
</tr><tr>
<th>Group 01</th>
<td>
<input type="text" tabindex="1" class="sample-value"
name="edtG01S01" id="edtG01S01"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S01" id="cbxG01S01"/> <1
</td>
<td>
<input type="text" tabindex="2" class="sample-value"
name="edtG01S02" id="edtG01S02"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S02" id="cbxG01S02"/> <1
</td>
<td>
<input type="text" tabindex="3" class="sample-value"
name="edtG01S03" id="edtG01S03" disabled="disabled"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S03" id="cbxG01S03"/> <1
</td>
<td>
<input type="text" tabindex="4" class="sample-value"
name="edtG01S04" id="edtG01S04"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S04" id="cbxG01S04"/> <1
</td>
<td>
<input type="text" tabindex="5" class="sample-value"
name="edtG01S05" id="edtG01S05"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S05" id="cbxG01S05"/> <1
</td>
</tr><tr>
<th>Group 02</th>
<td>
<input type="text" tabindex="6" class="sample-value"
name="edtG02S01" id="edtG02S01"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S01" id="cbxG02S01"/> <1
</td>
<td>
<input type="text" tabindex="7" class="sample-value"
name="edtG02S02" id="edtG02S02"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S02" id="cbxG02S02"/> <1
</td>
<td>
<input type="text" tabindex="8" class="sample-value"
name="edtG02S03" id="edtG02S03" disabled="disabled"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S03" id="cbxG02S03"/> <1
</td>
<td>
<input type="text" tabindex="9" class="sample-value"
name="edtG02S04" id="edtG01S04"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S04" id="cbxG02S04"/> <1
</td>
<td>
<input type="text" tabindex="10" class="sample-value"
name="edtG02S05" id="edtG02S05"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S05" id="cbxG02S05"/> <1
</td>
</tr></table>
</body></html>
输入有 class sample-value
,目前我最接近的工作是:
$('input.sample-value').keyup(function(event) {
if (event.which == 39) { /* right arrow key */
$(this).parent('td').next('td').find('input.sample-value').focus();
event.preventDefault();
}
if (event.which == 37) { /* left arrow key */
$(this).parent('td').prev('td').find('input.sample-value').focus();
event.preventDefault();
}
});
使用上面的代码,左右箭头键可以按预期在输入之间导航,直到您到达禁用的输入,或者直到您到达一行的末尾。此时,它无法向前或向后跳到下一个可聚焦输入。
有没有一种方法可以使这段代码足够灵活,以导航到适当的input.sample-value
元素,而不管它位于表格行或列中的什么位置,并且能够考虑跳过禁用的输入?输入在页面加载时不会被禁用,而是动态启用或禁用以响应在这些输入之前的下拉列表中选择的选项。
完整的工作示例:
$('input.sample-value').keyup(function(event) {
if (event.which == 39) { /* right arrow key */
$(this).parent('td').next('td').find('input.sample-value').focus();
event.preventDefault();
}
if (event.which == 37) { /* left arrow key */
$(this).parent('td').prev('td').find('input.sample-value').focus();
event.preventDefault();
}
});
* {
font-family: Arial;
}
input.sample-value {
width: 50px;
}
th, td {
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html><body>
<table><tr>
<th></th>
<th>Sample<br/>01</th>
<th>Sample<br/>02</th>
<th>Sample<br/>03</th>
<th>Sample<br/>04</th>
<th>Sample<br/>05</th>
</tr><tr>
<th>Group 01</th>
<td>
<input type="text" tabindex="1" class="sample-value"
name="edtG01S01" id="edtG01S01"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S01" id="cbxG01S01"/> <1
</td>
<td>
<input type="text" tabindex="2" class="sample-value"
name="edtG01S02" id="edtG01S02"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S02" id="cbxG01S02"/> <1
</td>
<td>
<input type="text" tabindex="3" class="sample-value"
name="edtG01S03" id="edtG01S03" disabled="disabled"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S03" id="cbxG01S03"/> <1
</td>
<td>
<input type="text" tabindex="4" class="sample-value"
name="edtG01S04" id="edtG01S04"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S04" id="cbxG01S04"/> <1
</td>
<td>
<input type="text" tabindex="5" class="sample-value"
name="edtG01S05" id="edtG01S05"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S05" id="cbxG01S05"/> <1
</td>
</tr><tr>
<th>Group 02</th>
<td>
<input type="text" tabindex="6" class="sample-value"
name="edtG02S01" id="edtG02S01"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S01" id="cbxG02S01"/> <1
</td>
<td>
<input type="text" tabindex="7" class="sample-value"
name="edtG02S02" id="edtG02S02"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S02" id="cbxG02S02"/> <1
</td>
<td>
<input type="text" tabindex="8" class="sample-value"
name="edtG02S03" id="edtG02S03" disabled="disabled"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S03" id="cbxG02S03"/> <1
</td>
<td>
<input type="text" tabindex="9" class="sample-value"
name="edtG02S04" id="edtG01S04"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S04" id="cbxG02S04"/> <1
</td>
<td>
<input type="text" tabindex="10" class="sample-value"
name="edtG02S05" id="edtG02S05"/>
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S05" id="cbxG02S05"/> <1
</td>
</tr></table>
</body></html>
也可用作 JSFiddle:https ://jsfiddle.net/zoLwv5d9/
解决方案
我对您的代码进行了一些更改,因此它现在跳过禁用的输入并在到达结束或开始时跳转到第一个/最后一个。
var next = $(this).parent('td').next('td');
if (next.length == 0) {
next = $(this).closest("tr").find("td:first")
} else if (next.find("input:disabled").length > 0) {
next = next.next("td")
}
next.find('input.sample-value').focus();
event.preventDefault();
演示
$('input.sample-value').keyup(function(event) {
if (event.which == 39) { /* right arrow key */
var next = $(this).parent('td').next('td');
if (next.length == 0) {
next = $(this).closest("tr").find("td:first")
} else if (next.find("input:disabled").length > 0) {
next = next.next("td")
}
next.find('input.sample-value').focus();
event.preventDefault();
}
if (event.which == 37) { /* left arrow key */
var prev = $(this).parent('td').prev('td');
if (prev.length == 0) {
prev = $(this).closest("tr").find("td:last")
} else if (prev.find("input:disabled").length > 0) {
prev = prev.prev("td")
}
prev.find('input.sample-value').focus();
event.preventDefault();
}
});
* {
font-family: Arial;
}
input.sample-value {
width: 50px;
}
th,
td {
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<table>
<tr>
<th></th>
<th>Sample<br/>01</th>
<th>Sample<br/>02</th>
<th>Sample<br/>03</th>
<th>Sample<br/>04</th>
<th>Sample<br/>05</th>
</tr>
<tr>
<th>Group 01</th>
<td>
<input type="text" tabindex="1" class="sample-value" name="edtG01S01" id="edtG01S01" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S01" id="cbxG01S01" /> <1
</td>
<td>
<input type="text" tabindex="2" class="sample-value" name="edtG01S02" id="edtG01S02" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S02" id="cbxG01S02" /> <1
</td>
<td>
<input type="text" tabindex="3" class="sample-value" name="edtG01S03" id="edtG01S03" disabled="disabled" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S03" id="cbxG01S03" /> <1
</td>
<td>
<input type="text" tabindex="4" class="sample-value" name="edtG01S04" id="edtG01S04" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S04" id="cbxG01S04" /> <1
</td>
<td>
<input type="text" tabindex="5" class="sample-value" name="edtG01S05" id="edtG01S05" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG01S05" id="cbxG01S05" /> <1
</td>
</tr>
<tr>
<th>Group 02</th>
<td>
<input type="text" tabindex="6" class="sample-value" name="edtG02S01" id="edtG02S01" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S01" id="cbxG02S01" /> <1
</td>
<td>
<input type="text" tabindex="7" class="sample-value" name="edtG02S02" id="edtG02S02" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S02" id="cbxG02S02" /> <1
</td>
<td>
<input type="text" tabindex="8" class="sample-value" name="edtG02S03" id="edtG02S03" disabled="disabled" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S03" id="cbxG02S03" /> <1
</td>
<td>
<input type="text" tabindex="9" class="sample-value" name="edtG02S04" id="edtG01S04" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S04" id="cbxG02S04" /> <1
</td>
<td>
<input type="text" tabindex="10" class="sample-value" name="edtG02S05" id="edtG02S05" />
<br/>
<input type="checkbox" tabindex="-1" name="cbxG02S05" id="cbxG02S05" /> <1
</td>
</tr>
</table>
</body>
</html>
推荐阅读
- vba - 访问表单文本框的验证规则
- regex - wp-cli search-replace 使用正则表达式时不替换
- r - R - 提取名称为 X 的列表的所有元素
- ios - URLSessionConfiguration 的 httpMaximumConnectionsPerHost 在网络故障的情况下不起作用
- html - 当来自 api 的响应不完全有角度时,如何跳过 ngFor?
- java - ApiResponses 混淆 Swagger-UI 输出找不到“类型”
- javascript - jQuery 用于根据下拉列表的更改值在 asp 中继器中设置背景颜色
- python - 我可以使用 ktrain 库从检查点恢复训练吗?
- python - 使用 to_sql 将 Pandas 数据帧中的数据批量插入 Sybase 数据库表失败
- java - 在 Java 中显示 3D 数组中的值