选项卡上的按键事件行为
Posted
技术标签:
【中文标题】选项卡上的按键事件行为【英文标题】:Keyup event behavior on tab 【发布时间】:2013-08-03 21:55:08 【问题描述】: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) 如果您一直按住选项卡直到它移出两个字段,则根本不会触发该事件。
【问题讨论】:
【参考方案1】:一个键的默认操作是在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 键,您可以在处理其他键之前进行任何必要的调整。 See your updated fiddle for an exampe.
编辑
根据您的评论,我改进了该功能。 javascript 最终变得有点复杂,但我会尽力解释。 Follow along with the new demo here.
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
提供了背景作为视觉辅助)。因此,无论按下什么键,只要它也有.captureKeys
,它所按下的当前元素都会被赋予.focus
类。
接下来,当keyup
在任何地方 被触发时(不仅仅是在.captureKeys
元素上),该函数会检查它是否是一个选项卡。如果是,那么焦点已经转移,自定义的.keyAction()
函数会在最后一个获得焦点的元素(.focus
)上调用。如果它不是选项卡,则在当前元素上调用 .keyAction()
(但同样,仅当它具有 .captureKeys
时)。
这应该可以达到你想要的效果。您可以在keyAction()
函数中使用变量theKey
来跟踪which key was pressed,并采取相应措施。
对此的一个主要警告:如果 .captureKeys
元素是 DOM 中的最后一个元素,在大多数浏览器中,按 Tab 将移除文档的焦点,keyup
事件将从不开火。这就是我在演示底部添加虚拟链接的原因。
这提供了一个基本框架,因此您可以根据自己的需要对其进行修改。希望对您有所帮助。
【讨论】:
您的解决方案在第一个字段中引入了一个额外的空格字符。另外,我只想避免 tab 和 shift + tab 上的 keyup 事件。【参考方案2】:这是预期的行为。如果我们看看发生的一系列事件:
-
焦点位于第一个文本框时按 Tab 键
在第一个文本框触发按键事件
将焦点移到第二个文本框
手指离开 Tab 键
Keyup 事件在第二个文本框触发
为第二个文本框触发 Key up,因为这是焦点转移到该输入后发生的位置。
您无法阻止这一系列事件的发生,但您可以检查事件以查看按下了哪个键,如果是 Tab 键,则调用 preventDefault()
。
【讨论】:
【参考方案3】:我最近正在为placeholder 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
);
【讨论】:
【参考方案4】:我最终使用了这个解决方案:
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/
【讨论】:
以上是关于选项卡上的按键事件行为的主要内容,如果未能解决你的问题,请参考以下文章