HTML表行在JQuery中通过键盘导航



我有一个由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的情况下,类的操作是不必要的——它只对UpDown键很重要。因此,您应该仅在以下两种情况下删除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>

最新更新