简体   繁体   English

Javascript / jQuery防止双重事件触发

[英]Javascript/jQuery prevent double event triggers

I have an html form. 我有一个HTML表单。

  1. It uses keyboard navigation (with arrow keys) to move between fields including the "enter" key. 它使用键盘导航(带有箭头键)在包括“输入”键的字段之间移动。
  2. It periodically needs to prompt the user for acceptance of information. 它定期需要提示用户接受信息。
  3. The enter key is picked up on both the button and in the form field. 在按钮和表单字段中都可以按Enter键。

Problem: When the user hits "ENTER" on the accept button it is triggering double events in my form. 问题:当用户在接受按钮上单击“ ENTER”时,它会触发表单中的双重事件。 Shifting the focus 2 fields instead of 1. 将焦点从2移到1。

I have code that demonstrates exactly what I'm talking about here: 我有一些代码可以确切地说明我在这里所说的内容:

Original Post http://jsfiddle.net/mcraig_brs/UgUUr/1/ 原始帖子 http://jsfiddle.net/mcraig_brs/UgUUr/1/

Modified Post http://jsfiddle.net/mcraig_brs/UgUUr/2/ 修改后的文章http://jsfiddle.net/mcraig_brs/UgUUr/2/

Here is the sample HTML: 这是示例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>

Here is the sample JS: 这是示例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;
    }   
});

When I press "ENTER" while the focus is on the button in the current code I get the following output in the log div: 当我将焦点放在当前代码中的按钮上时按“ ENTER”时,将在log div中获得以下输出:

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

(At the moment in jsFiddle the only way I can get to the button is to focus on the first text field and "shift+tab" back to it so it has focus, so that I can press "ENTER" on it. But in the live code it is automatically focused for the user.) (目前,在jsFiddle中,我到达按钮的唯一方法是将焦点放在第一个文本字段上,然后将其“ shift + tab”放回到它上面,以便它具有焦点,以便可以在其上按“ ENTER”。实时代码,它会自动针对用户。)

Question: How can I prevent this type of double event from triggering? 问题:如何防止此类双重事件触发? I have tried e.stopPropagation() but that did not yield the results I was looking for. 我尝试了e.stopPropagation(),但是没有得到我想要的结果。 When the user pressed "ENTER" i want the focus to advance only 1 field. 当用户按下“ ENTER”时,我希望焦点仅前进1个字段。

I have been wrestling with this for a few days so any help would be greatly appreciated. 我已经为此奋斗了几天,所以任何帮助将不胜感激。 Please note that if a user clicks on the button with the mouse it works properly, it is only the ENTER key that triggers the double event. 请注意,如果用户用鼠标单击该按钮,它将正常工作,只有ENTER键才能触发double事件。

Note: I had to modify my question slightly to better convey the constraints. 注意:我必须稍微修改我的问题,以更好地传达约束。

keyup is triggering the issue, change it to keypress 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;
    }   
});

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

keypress 按键

Fires when an actual character is being inserted in, for instance, a text input. 当在例如文本输入中插入实际字符时触发。 It repeats while the user keeps the key depressed. 在用户按住键的同时重复此操作。

keyup KEYUP

Fires when the user releases a key, after the default action of that key has been performed. 在执行用户默认键后释放用户键时触发。

---- edit --- ----编辑-

To catch key press and keyup both, I would suggest to define it separately, http://jsfiddle.net/UgUUr/3/ 为了同时捕捉按键和按键,我建议分别定义它, 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;
    }   
});

Use keypress event instead: 改用按键事件:

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

DEMO DEMO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM