提琴: https://jsfiddle.net/pegarm/aq9Laaew/272358/
我正在创建一个实用程序,该实用程序应模仿并像由元素表组成的电子表格一样工作。我创建了jQuery处理程序,该处理程序支持使用Tab,Enter和箭头键在此表的“单元格”之间进行导航。
现在我的“概念验证”代码如下:
$('input.field').keydown(function(event) {
var
$this = $(this),
Row = getRow($this),
Row_Next = (parseInt(Row) + 1).toString(),
Row_Prev = (parseInt(Row) - 1).toString(),
cursorPosition = $this.getCaret();
switch (event.which) {
/* Enter */
case 13:
event.preventDefault();
if ($this.hasClass('last') && Row != '18') {
$this.closest('tbody').find('tr[data-row="' + Row_Next + '"]').find('input[name="' + $this.attr('data-next') + '"]').focus();
} else if (!$this.hasClass('last')) {
$this.closest('tr[data-row="' + Row + '"]').find('input[name="' + $this.attr('data-next') + '"]').focus();
}
break;
/* Left */
case 37:
if ($this.hasClass('first') && cursorPosition == 0 && Row != '1') {
$this.closest('tbody').find('tr[data-row="' + Row_Prev + '"]').find('input[name="' + $this.attr('data-prev') + '"]').focus();
} else if (!$this.hasClass('first') && cursorPosition == 0) {
$this.closest('tbody').find('tr[data-row="' + Row + '"]').find('input[name="' + $this.attr('data-prev') + '"]').focus();
}
break;
/* Up */
case 38:
if (Row != '1') {
$this.closest('tbody').find('tr[data-row="' + Row_Prev + '"]').find('input[name="' + $this.attr('name') + '"]').focus();
}
break;
/* Right */
case 39:
if ($this.hasClass('last') && cursorPosition == $this.val().length && Row != '18') {
$this.closest('tbody').find('tr[data-row="' + Row_Next + '"]').find('input[name="' + $this.attr('data-next') + '"]').focus();
} else if (!$this.hasClass('last') && cursorPosition == $this.val().length) {
$this.closest('tr[data-row="' + Row + '"]').find('input[name="' + $this.attr('data-next') + '"]').focus();
}
break;
/* Down */
case 40:
if (Row != '18') {
$this.closest('tbody').find('tr[data-row="' + Row_Next + '"]').find('input[name="' + $this.attr('name') + '"]').focus();
}
break;
}
});
我遇到的问题是,当用户按Tab键在各个字段之间导航时,页面会自动选择下一个字段的内容,从而允许他们开始键入并覆盖其值。当用户使用箭头键在单元格之间导航时,内容不会突出显示,从而迫使他们在键入新值之前删除内容。
我尝试过的不起作用的东西:
$('input.field').focus(function() {
$(this).select();
});
...和
$this.closest('tbody').find('tr[data-row="' + Row_Next + '"]').find('input[name="' + $this.attr('name') + '"]').focus().select();
...和
$this.closest('tbody').find('tr[data-row="' + Row_Next + '"]').find('input[name="' + $this.attr('name') + '"]').select().focus();
...并将keydown事件处理程序更改为:
$('input.field').mouseup(function(e) {
return false;
}).focus(function() {
$(this).select();
}).keydown(function(event) {...
我正在拔头发。当使用箭头键聚焦输入字段时,我似乎什么也没允许聚焦输入字段的内容。
答案 0 :(得分:2)
似乎是时间问题(至少在Chrome中是这样)。当我将其包装为超时时,它似乎具有所需的结果:
Right */
case 39:
if ($this.hasClass('last') && cursorPosition == $this.val().length && Row != '18') {
setTimeout(() => {
$this.closest('tbody')
.find('tr[data-row="' + Row_Next + '"]')
.find('input[name="' + $this.attr('data-next') + '"]')
.focus()
.select();
}, 10);
} else if (!$this.hasClass('last') && cursorPosition == $this.val().length) {
setTimeout(() => {
$this.closest('tr[data-row="' + Row + '"]')
.find('input[name="' + $this.attr('data-next') + '"]')
.focus()
.select();
}, 10);
}
break;
更新1 似乎是我所怀疑的,浏览器需要在光标所在的输入中继续该事件。更好的解决方案是防止发生任何默认情况:
Right */
case 39:
if ($this.hasClass('last') && cursorPosition == $this.val().length && Row != '18') {
event.preventDefault();
$this.closest('tbody')
.find('tr[data-row="' + Row_Next + '"]')
.find('input[name="' + $this.attr('data-next') + '"]')
.focus()
.select();
} else if (!$this.hasClass('last') && cursorPosition == $this.val().length) {
event.preventDefault();
$this.closest('tr[data-row="' + Row + '"]')
.find('input[name="' + $this.attr('data-next') + '"]')
.focus()
.select();
}
break;