19

HTML:

<form id="myform">
    <input id="firstfield" name="firstfield" value="100" type="text" />
    <input id="secondfield" name="secondfield" value="200" type="text" />
</form>

jQuery:

jQuery(document).ready(function() {
    $('#firstfield').keyup(function() {
      alert('Handler for firstfield .keyup() called.');
    });
    $('#secondfield').keyup(function() {
      alert('Handler for secondfield .keyup() called.');
    });
});

演示:http: //jsfiddle.net/KtSja/3/

在此演示中,如果您将光标放在第一个字段中,然后跳出(不进行任何更改),则在第二个字段上触发 keyup 事件。即,您正在跳出第一个字段并进入第二个字段。这种行为正确吗?我怎样才能防止这种情况发生?同样适用于 shift + tab。

笔记:

a)我相信所有其他键,可打印和不可打印,都会在第一个字段上触发 keyup 事件。

b)如果您按住选项卡直到它移出两个字段,则根本不会触发该事件。

4

4 回答 4

14

一个键的默认动作是在keydown事件期间执行的,所以很自然地,随着时间的推移keyup,Tab 键已经将焦点转移到下一个字段。

您可以使用:

jQuery(document).ready(function() {
    $('#firstfield, #secondfield').on({
        "keydown": function(e) {
            if (e.which == 9) {
                alert("TAB key for " + $(this).attr("id") + " .keydown() called.");
            }
        },
        "keyup": function(e) {
            if (e.which != 9) {
                alert("Handler for " + $(this).attr("id") + " .keyup() called.");
            }
        }
    });
});

这样,如果按下 Tab 键,您可以在处理其他键之前进行任何必要的调整。请参阅您更新的小提琴以获取示例。

编辑

根据您的评论,我修改了该功能。JavaScript 最终变得有点复杂,但我会尽力解释。在此处跟随新的演示。

jQuery(document).ready(function() {
    (function($) {
        $.fn.keyAction = function(theKey) {
            return this.each(function() {
                if ($(this).hasClass("captureKeys")) {
                    alert("Handler for " + $(this).attr("id") + " .keyup() called with key "+ theKey + ".");
                    // KeyCode dependent statements go here.
                }
            });
        };
    })(jQuery);

    $(".captureKeys").on("keydown", function(e) {
        $("*").removeClass("focus");
        $(this).addClass("focus");
    });
    $("body").on("keyup", "*:focus", function(e) {
        if (e.which == 9) {
            $(".focus.captureKeys").keyAction(e.which);
            $("*").removeClass("focus");
        }
        else {
            $(this).keyAction(e.which);
        }
    });
});

基本上,你给class="captureKeys"你想要监控按键的任何元素。首先看第二个函数:当keydown你的一个元素被触发时captureKeys,它被赋予了一个名为focus. 这只是为了跟踪最近的元素以获得焦点(我.focus在演示中给出了背景作为视觉辅助)。因此,无论按下什么键.focus,只要它也有.captureKeys.

接下来,当在任何地方(不仅仅是元素)keyup触发时,该函数会检查它是否是一个选项卡。如果是,那么焦点已经转移,并且在最后一个获得焦点的元素上调用自定义函数 ( )。如果它不是选项卡,则在当前元素上调用 then (但同样,仅当它具有 时)。.captureKeys.keyAction().focus.keyAction().captureKeys

这应该达到你想要的效果。您可以使用函数中的变量theKeykeyAction()跟踪按下了哪个键,并采取相应的行动。

对此的一个主要警告:如果一个.captureKeys元素是 DOM 中的最后一个元素,则在大多数浏览器中按 Tab 键会从文档中移除焦点,并且该keyup事件永远不会触发。这就是我在演示底部添加虚拟链接的原因。

这提供了一个基本框架,因此您可以根据需要对其进行修改。希望能帮助到你。

于 2013-08-02T15:06:07.367 回答
5

这是预期的行为。如果我们看看发生的一系列事件:

  1. 焦点位于第一个文本框时按 Tab 键
  2. 在第一个文本框上触发按键事件
  3. 将焦点移到第二个文本框
  4. 将手指从 Tab 键上抬起
  5. 在第二个文本框上触发 Keyup 事件

为第二个文本框触发 Key up,因为这是焦点转移到该输入后发生的位置。

您无法阻止这一系列事件的发生,但您可以检查事件以查看按下了哪个键,preventDefault()如果是 tab 键则调用。

于 2013-08-02T15:05:56.163 回答
4

我最近正在处理这个占位符 polyfill。我发现如果您想在原始字段中捕获 keyup 事件,您可以监听 keydown 事件并在按下选项卡时触发 keyup 事件。

而不是这个:

$(this).on({'keyup': function() {
                //run code here
            }
        });

改成这样:

$(this).on({'keydown': function(e) {
                // if tab key pressed - run keyup now
                if (e.keyCode == 9) {
                    $(this).keyup();
                    e.preventDefault;
                }
            },
            'keyup': function() {
                //run code here
            }
        });
于 2014-07-03T21:12:37.433 回答
2

我最终使用了这个解决方案:

HTML:

<form id="myform">
    <input id="firstfield" name="firstfield" value="100" type="text" />
    <input id="secondfield" name="secondfield" value="200" type="text" />
</form>

jQuery:

jQuery(document).ready(function () {
    $('#firstfield').keyup(function (e) {
        var charCode = e.which || e.keyCode; // for cross-browser compatibility
        if (!((charCode === 9) || (charCode === 16)))
            alert('Handler for firstfield .keyup() called.');
    });
    $('#secondfield').keyup(function (e) {
       var charCode = e.which || e.keyCode; // for cross-browser compatibility
       if (!((charCode === 9) || (charCode === 16)))
            alert('Handler for secondfield .keyup() called.');
    });
});

如果键是 tab、shift 或两者,此解决方案不会运行警报。

解决方案:http: //jsfiddle.net/KtSja/13/

于 2013-08-03T12:15:50.710 回答