选项卡上的Keyup事件行为
HTML:
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)我相信所有其他键,可打印和不可打印,在第一个字段上触发键盘事件。
b)如果按住标签直到它移出两个字段,则根本不会触发事件。
在keydown
事件期间执行键的默认操作,因此,当键盘传播时,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键,您可以在处理其他键之前进行任何必要的调整。 有关例子,请参阅最新的小提琴。
编辑
根据你的评论,我改进了这个function。 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"
赋予您要监视按键的任何元素。 首先看一下第二个函数:当你的captureKeys
元素触发keydown
, captureKeys
它一个名为focus
的虚拟类。 这只是为了跟踪最近的焦点元素(我已经将.focus
作为视觉辅助在演示中给出了背景)。 因此,无论按下什么键,它被按下的当前元素都会被赋予.focus
类,只要它也有.captureKeys
。
接下来,当keyup
在任何地方 (不仅仅是.captureKeys
元素)被触发时,该函数会检查它是否是一个标签。 如果是,则焦点已经移动,并且在最后一个具有焦点( .focus
)的元素上调用自定义.keyAction()
函数。 如果它不是制表符,则在当前元素上调用.keyAction()
(但同样,仅当它具有.captureKeys
)。
这应该达到你想要的效果。 您可以在keyAction()
函数中使用变量keyAction()
来跟踪按下的键 ,并采取相应的操作。
一个主要的警告: 如果.captureKeys
元素是DOM中的最后一个元素 ,按Tab键将在大多数浏览器中从文档中删除焦点,并且keyup
事件永远不会触发。 这就是为什么我在演示的底部添加了虚拟链接。
这提供了一个基本框架,因此您可以根据自己的需要对其进行修改。 希望能帮助到你。
我最近在处理占位符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 } });
这是预期的行为。 如果我们看一系列发生的事件:
- 当焦点位于第一个文本框时按Tab键
- 在第一个文本框上触发按键事件
- 将焦点移动到第二个文本框
- 将手指抬离Tab键
- 键盘事件在第二个文本框中触发
为第二个文本框触发了键,因为这是因为焦点已转移到该输入而发生的位置。
您无法阻止这一系列事件发生,但您可以检查事件以查看按下了哪个键,如果是Tab键,则调用preventDefault()
。
我最终使用了这个解决方案:
HTML:
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/