我有一个由Ajax
创建的HTML表。此表的渲染标记如下:
<table class="table" id="tbl_byKeyboard">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Customer</th>
<th>Discount</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="radio" name="bid" value="122">
</td>
<td>2022-10-01</td>
<td>Customer 01</td>
<td>10%</td>
<td>1000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="123">
</td>
<td>2022-10-01</td>
<td>Customer 02</td>
<td>10%</td>
<td>2000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="124">
</td>
<td>2022-10-01</td>
<td>Customer 03</td>
<td>10%</td>
<td>3000.00</td>
</tr>
</tbody>
</table>
使用这个表,基本上我想使用键盘上的"向上"one_answers"向下"箭头键导航表行。选择右侧行后,用户应能够通过按下回车键来检查单选按钮(在所选行内(。
这是我的jQuery
代码:
$(document).ready(function() {
$(document).on('click', "#tbl_byKeyboard tbody tr", function(e) {
var inp = this.querySelector('input')
if (inp == null) return
if (e.target.tagName != "INPUT") {
inp.checked = !inp.checked
}
$('#tbl_byKeyboard tbody tr').removeClass('active');
$(this).addClass('active');
})
});
$(window).on('keydown', tbl_navigate)
function tbl_navigate(e) {
var $tbl = $('#tbl_byKeyboard');
var $cur = $('.active', $tbl).removeClass('active').first();
if (e.keyCode === 40) { //down
if ($cur.length) {
$cur.next().addClass('active');
} else {
$tbl.children().first().addClass('active');
}
} else if (e.keyCode == 38) { //up
if ($cur.length) {
$cur.prev().addClass('active');
} else {
$tbl.children().last().addClass('active');
}
} else if (e.keyCode == 13) { //enter
var $this = $cur;
var inp = $this.find('input')
if (inp == null) return
if (inp.is(':checked')) {
inp.prop('checked', false);
} else {
inp.prop('checked', true);
$('#tbl_byKeyboard tbody tr').removeClass('active');
$this.addClass('active');
}
}
}
堆栈片段:
$(document).ready(function() {
$(document).on('click', "#tbl_byKeyboard tbody tr", function(e) {
var inp = this.querySelector('input')
if (inp == null) return
if (e.target.tagName != "INPUT") {
inp.checked = !inp.checked
}
$('#tbl_byKeyboard tbody tr').removeClass('active');
$(this).addClass('active');
})
});
$(window).on('keydown', tbl_navigate)
function tbl_navigate(e) {
var $tbl = $('#tbl_byKeyboard');
var $cur = $('.active', $tbl).removeClass('active').first();
if (e.keyCode === 40) { //down
if ($cur.length) {
$cur.next().addClass('active');
} else {
$tbl.children().first().addClass('active');
}
} else if (e.keyCode == 38) { //up
if ($cur.length) {
$cur.prev().addClass('active');
} else {
$tbl.children().last().addClass('active');
}
} else if (e.keyCode == 13) { //enter
var $this = $cur;
var inp = $this.find('input')
if (inp == null) return
if (inp.is(':checked')) {
inp.prop('checked', false);
} else {
inp.prop('checked', true);
$('#tbl_byKeyboard tbody tr').removeClass('active');
$this.addClass('active');
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table" id="tbl_byKeyboard">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Customer</th>
<th>Discount</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="radio" name="bid" value="122">
</td>
<td>2022-10-01</td>
<td>Customer 01</td>
<td>10%</td>
<td>1000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="123">
</td>
<td>2022-10-01</td>
<td>Customer 02</td>
<td>10%</td>
<td>2000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="124">
</td>
<td>2022-10-01</td>
<td>Customer 03</td>
<td>10%</td>
<td>3000.00</td>
</tr>
</tbody>
</table>
我的问题是,使用此代码,我可以使用"向上"one_answers"向下"箭头键导航表行,但输入键对我不起作用。
希望有人能帮我弄清楚。
问题是,在keydown
处理程序的开头,您删除了类active
:
var $cur = $('.active', $tbl).removeClass('active').first();
但在if
中,对于Enter
,当检查输入时,您不会再次设置该类:
if (inp.is(':checked')) {
inp.prop('checked', false);
}
此外,在Enter
的情况下,类的操作是不必要的——它只对Up
和Down
键很重要。因此,您应该仅在以下两种情况下删除active
类:
var $cur = $('.active', $tbl).first();
if (e.keyCode === 40) { //down
$cur.removeClass('active');
...
} else if (e.keyCode == 38) { //up
$cur.removeClass('active');
...
}
因为没有必要删除Enter
的情况,所以可以省略它:
if (inp.is(':checked')) {
inp.prop('checked', false);
} else {
inp.prop('checked', true);
}
工作示例:
我添加了一条细线来聚焦演示的第一个单选按钮:
$('#tbl_byKeyboard input[type=radio]').eq(0).focus();
$(document).ready(function() {
$('#tbl_byKeyboard input[type=radio]').eq(0).focus();
$(document).on('click', "#tbl_byKeyboard tbody tr", function(e) {
var inp = this.querySelector('input')
if (inp == null) return
if (e.target.tagName != "INPUT") {
inp.checked = !inp.checked
}
$('#tbl_byKeyboard tbody tr').removeClass('active');
$(this).addClass('active');
})
});
$(window).on('keydown', tbl_navigate)
function tbl_navigate(e) {
var $tbl = $('#tbl_byKeyboard');
var $cur = $('.active', $tbl).first();
if (e.keyCode === 40) { //down
$cur.removeClass('active');
if ($cur.length) {
$cur.next().addClass('active');
} else {
$tbl.children().first().addClass('active');
}
} else if (e.keyCode == 38) { //up
$cur.removeClass('active');
if ($cur.length) {
$cur.prev().addClass('active');
} else {
$tbl.children().last().addClass('active');
}
} else if (e.keyCode == 13) { //enter
var $this = $cur;
var inp = $this.find('input')
if (inp == null) return
if (inp.is(':checked')) {
inp.prop('checked', false);
} else {
inp.prop('checked', true);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table" id="tbl_byKeyboard">
<thead>
<tr>
<th>#</th>
<th>Date</th>
<th>Customer</th>
<th>Discount</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="radio" name="bid" value="122">
</td>
<td>2022-10-01</td>
<td>Customer 01</td>
<td>10%</td>
<td>1000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="123">
</td>
<td>2022-10-01</td>
<td>Customer 02</td>
<td>10%</td>
<td>2000.00</td>
</tr>
<tr>
<td>
<input type="radio" name="bid" value="124">
</td>
<td>2022-10-01</td>
<td>Customer 03</td>
<td>10%</td>
<td>3000.00</td>
</tr>
</tbody>
</table>