1

我有一个按钮和一系列文本字段。我正在尝试促进键盘导航。这是我所拥有的:

HTML

<button id="button1">Click me</button>
<input type="text" id="field1" name="field1">
<input type="text" id="field2" name="field2">
<input type="text" id="field3" name="field3">

JS/JQUERY v 1.9.1

/* If they click the button */
$('#button1').on('click', function() {
    moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});
/* If they hit "enter" on the button */
$('#button1').on('keyup', function(e) {
    if (e.which === 13) {
        moveToNextInputField();
    }
});
/* Capture keyboard input to limit to Numbers */
$('input').on('keydown', function (e) {
    switch(e.which) {
        case 48:
        case 49:
        case 50: /* All numbers, or wanted keys, etc.... */
            $(this).data('changed', true);
            break;
        default:
            e.preventDefault();  /* prevent other unwanted keys from doing anything */
            break;
    }
});
/* Capture keyboard input for keyboard navigation */
$('input').on('keyup', function (e) {
    switch (e.which) {
        /* other cases to do stuff excluded */
        case 13:
            moveToNextInputField();
            break;
    }
});

我遇到的问题是在 Firefox 和 IE10(可能还有其他)中,当我选择按钮并按“ENTER”时,它会触发 2 个事件。第一个事件将焦点移动到下一个字段,第二个事件做同样的事情。看来我不能足够快地按下“ENTER”键。当我运行此代码并按按钮上的“输入”时,我最终进入了 field2。

所以我的问题是:是否可以“锁定”一个事件,使其只触发一个事件而不是几个?

作为旁注,如果有更好的方法可以做到这一点,我会全力以赴。


解决方案:

我发现我的答案是推荐的东西的组合。

  1. 我确实摆脱了 $('#button1').on('keyup'....)。这是多余的。
  2. 我在 $('#button').click(...) 函数中添加了 e.stopImmediatePropigation() 。这解决了我的问题。

以下是有效的解决方案:

/* If they click the button or press ENTER while focused */
$('#button1').on('click', function(e) {
    e.stopImmediatePropigation(); 
    moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});

/* Capture keyboard input to limit to Numbers */
$('input').on('keydown', function (e) {
    switch(e.which) {
        case 48:
        case 49:
        case 50: /* All numbers, or wanted keys, etc.... */
            $(this).data('changed', true);
            break;
        default:
            e.preventDefault();  /* prevent other unwanted keys from doing anything */
            break;
    }
});
/* Capture keyboard input for keyboard navigation */
$('input').on('keyup', function (e) {
    switch (e.which) {
        /* other cases to do stuff excluded */
        case 13:
            moveToNextInputField();
            break;
    }
});

谢谢大家的帮助。希望这对其他人也有帮助。干杯。

4

3 回答 3

1

这很容易,当聚焦按钮并单击 enter 时,click 和 keyup 事件处理程序都会触发。

换句话说,聚焦一个按钮并按下回车将触发按钮上的点击事件,所以改变这个:

$('#button1').on('click', function() {
    moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});

$('#button1').on('keyup', function(e) {
    if (e.which === 13) {
        moveToNextInputField();
    }
});

只是:

$('#button1').on('click', function() {
    moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});

因为不需要 keyup 事件处理程序。

小提琴

作为旁注,您可以将其缩短为:

$('#button1').on('click', moveToNextInputField);
于 2013-07-10T21:09:12.210 回答
1

您必须注意到点击是一种特殊的事件。它在必须触发按钮功能时生成。所以它通常发生在 mousedown、ENTER 或 SPACE 之后。您可以应用一些解决方案

  1. e.preventDefault 在您识别 ENTER 键时在 keyUp 处理程序中。
  2. 使用 mousedown 而不是单击
  3. 完全删除点击处理程序(ENTER 和 SPACE 将触发它)。

顺便提一句。我还建议使用 keypress 而不是 keyup -看这里

于 2013-07-10T21:11:19.593 回答
0

您可以尝试使用 jQuery 的 deferred 来做到这一点。无论哪个先触发,您都可以将延迟对象设置为已解决。您可以检查对象的状态,以查看它是否第一次等待触发,而不是在已经解决时。

于 2013-07-10T20:56:37.070 回答