Javascript / jQuery防止双事件触发器

时间:2013-09-19 13:40:12

标签: javascript jquery html javascript-events

我有一个html表单。

  1. 它使用键盘导航(带箭头键)在字段之间移动,包括“输入”键。
  2. 它定期需要提示用户接受信息。
  3. 在按钮和表单字段中选择回车键。
  4. 问题:当用户在接受按钮上点击“ENTER”时,它会在我的表单中触发双重事件。将焦点移动2个字段而不是1个。

    我的代码完全展示了我在这里所说的内容:

    原帖 http://jsfiddle.net/mcraig_brs/UgUUr/1/

    修改后的帖子http://jsfiddle.net/mcraig_brs/UgUUr/2/

    以下是HTML示例:

    <button id="myButton">Press Enter On Me</button><br>
    <input type="text" id="text1" class="tInput" data-index="0"><br>
    <input type="text" id="text2" class="tInput" data-index="1"><br>
    <input type="text" id="text3" class="tInput" data-index="2"><br>
    <div id="log"></div>
    

    以下是JS示例:

    function log ( data ) {
        $('#log').append(data + "<br>");   
    }
    function focusOn(index) {
        log("focusOn(index): " + index);
        $('input.tInput').eq(index).focus();   
    }
    function focusNext( currentIndex ) {
        log("focusNext(currentIndex):" + currentIndex);
        focusOn(currentIndex + 1);
    }
    function focusPrevious (currentIndex) {
        log('focusPrevious(currentIndex):' + currentIndex);
        focusOn(currentIndex - 1);
    }
    $('#myButton').on('click', function(e) {
        log("event:click #myButton");
        focusOn(0);
    });
    $('input.tInput').on('keyup', function(e) {
        switch (e.which) {
            case 13:
                log("event:ENTER key in input.tInput");
                focusNext($(this).data('index'));
                break;
            case 38:
                log("event:UP ARROW key in input.tInput");
                focusPrevious($(this).data('index'));
                break;
            case 40:
                log('event:DOWN ARROW key in input.tInput');
                focusNext($(this).data('index'));
                break;
        }   
    });
    

    当焦点在当前代码中的按钮上时按“ENTER”时,我在日志div中得到以下输出:

    event:click #myButton
    focusOn(index): 0
    event:ENTER key in input.tInput
    focusNext(currentIndex):0
    focusOn(index): 1
    

    (在jsFiddle的那一刻,我可以到达按钮的唯一方法是将注意力集中在第一个文本字段和“shift + tab”上,使其具有焦点,这样我就可以按下“ENTER”了但是在实时代码中,它会自动聚焦给用户。)

    问题:如何防止此类双重事件触发?我尝试过e.stopPropagation()但是没有产生我想要的结果。当用户按下“ENTER”时,我希望焦点仅前进1个字段。

    我已经和它搏斗了几天,所以任何帮助都会非常感激。请注意,如果用户使用鼠标单击按钮它可以正常工作,则只有ENTER键才会触发双重事件。

    注意:我必须稍微修改我的问题以更好地传达约束。

2 个答案:

答案 0 :(得分:4)

keyup正在触发此问题,请将其更改为keypress

$('input.tInput').on('keypress', function(e) {
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

来自http://www.quirksmode.org/dom/events/keys.html

<强>按键

插入实际字符时触发,例如文本输入。当用户按下键时,它会重复。

<强> KEYUP

在执行该键的默认操作后,用户释放密钥时触发。

----编辑---

要抓住按键和按键,我建议单独定义,http://jsfiddle.net/UgUUr/3/

$('input.tInput').on('keypress', function(e) {
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

$('input.tInput').on('keyup', function(e) {
    switch (e.which) {
        case 38:
            log("event:UP ARROW key in input.tInput");
            focusPrevious($(this).data('index'));
            break;
        case 40:
            log('event:DOWN ARROW key in input.tInput');
            focusNext($(this).data('index'));
            break;
    }   
});

答案 1 :(得分:1)

改为使用按键事件:

$('input.tInput').on('keypress', function(e) {    
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

DEMO