javascript 选项卡上的键盘事件行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18020098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Keyup event behavior on tab
提问by Zero
HTML:
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:
jQuery(document).ready(function() {
$('#firstfield').keyup(function() {
alert('Handler for firstfield .keyup() called.');
});
$('#secondfield').keyup(function() {
alert('Handler for secondfield .keyup() called.');
});
});
Demo: http://jsfiddle.net/KtSja/3/
演示:http: //jsfiddle.net/KtSja/3/
In this demo, if you place your cursor in the first field and then tab out (without making any changes), the keyup event is fired on the second field. i.e., you are tabbing out of first field and into second field. Is this behavior correct? How can I prevent this from happening? Same applies to shift + tab.
在此演示中,如果您将光标放在第一个字段中,然后跳出(不做任何更改),则会在第二个字段上触发 keyup 事件。即,您正在跳出第一个字段并进入第二个字段。这种行为是否正确?我怎样才能防止这种情况发生?同样适用于 shift + tab。
Note:
笔记:
a) I believe all other keys, printable and non-printable, trigger the keyup event on the first field.
a)我相信所有其他键,可打印和不可打印,在第一个字段上触发 keyup 事件。
b) The event isn't triggered at all if you keep the tab pressed until it moves out of both fields.
b) 如果您按住选项卡直到它移出两个字段,则根本不会触发该事件。
采纳答案by Zero
I ended up using this solution:
我最终使用了这个解决方案:
HTML:
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:
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.');
});
});
This solution doesn't run the alert if the key is tab, shift or both.
如果键是 tab、shift 或两者,则此解决方案不会运行警报。
Solution: http://jsfiddle.net/KtSja/13/
解决方案:http: //jsfiddle.net/KtSja/13/
回答by theftprevention
A key's default action is performed during the keydown
event, so, naturally, by the time keyup
propagates, the Tab key has changed the focus to the next field.
在keydown
事件期间执行键的默认操作,因此,自然而然地,随着时间的推移keyup
,Tab 键已将焦点更改为下一个字段。
You can use:
您可以使用:
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.");
}
}
});
});
This way, if the Tab key is pressed, you can make any necessary adjustments before handling other keys. See your updated fiddle for an exampe.
这样,如果按下 Tab 键,您可以在处理其他键之前进行任何必要的调整。请参阅您更新的小提琴作为示例。
Edit
编辑
Based on your comment, I revamped the function. The JavaScript ended up being a bit complicated, but I'll do my best to explain. Follow along with the new demo here.
根据您的评论,我改进了该功能。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);
}
});
});
Basically, you give class="captureKeys"
to any elements on which you want to monitor keypresses. Look at that second function first: When keydown
is fired on one of your captureKeys
elements, it's given a dummy class called focus
. This is just to keep track of the most recent element to have the focus (I've given .focus
a background in the demo as a visual aid). So, no matter what key is pressed, the current element it's pressed over is given the .focus
class, as long as it also has .captureKeys
.
基本上,您可以class="captureKeys"
指定要监视按键的任何元素。首先看看第二个函数:当keydown
在你的一个captureKeys
元素上触发时,它被赋予一个名为focus
. 这只是为了跟踪最近的元素以获得焦点(我.focus
在演示中提供了背景作为视觉辅助)。因此,无论按下什么键,它所按下的当前元素都会被赋予.focus
类,只要它也有.captureKeys
.
Next, when keyup
is fired anywhere(not just on .captureKeys
elements), the function checks to see if it was a tab. If it was, then the focus has already moved on, and the custom .keyAction()
function is called on whichever element was the last one to have focus (.focus
). If it wasn't a tab, then .keyAction()
is called on the current element (but, again, only if it has .captureKeys
).
接下来,当keyup
在任何地方(不仅仅是在.captureKeys
元素上)被触发时,该函数会检查它是否是一个选项卡。如果是,则焦点已经移动,并且自定义.keyAction()
函数将在最后一个获得焦点的元素上调用 ( .focus
)。如果它不是选项卡,则.keyAction()
在当前元素上调用(但同样,仅当它具有 时.captureKeys
)。
This should achieve the effect you want. You can use the variable theKey
in the keyAction()
function to keep track of which key was pressed, and act accordingly.
这应该可以达到你想要的效果。您可以使用该变量theKey
的keyAction()
函数来跟踪该键被按下,并采取相应的行动。
One main caveat to this: if a .captureKeys
element is the last element in the DOM, pressing Tab will remove the focus from the document in most browsers, and the keyup
event will never fire. This is why I added the dummy link at the bottom of the demo.
对此的一个主要警告:如果一个.captureKeys
元素是 DOM 中的最后一个元素,则在大多数浏览器中按 Tab 键将从文档中移除焦点,并且该keyup
事件永远不会触发。这就是我在演示底部添加虚拟链接的原因。
This provides a basic framework, so it's up to you to modify it to suit your needs. Hope it helps.
这提供了一个基本框架,因此您可以对其进行修改以满足您的需要。希望能帮助到你。
回答by Josh
It is expected behavior. If we look at the series of events happening:
这是预期的行为。如果我们看看发生的一系列事件:
- Press Tab Key while focus is on first text box
- Trigger key down event on first text box
- Move focus to second text box
- Lift finger off tab key
- Keyup event is triggered on second text box
- 当焦点位于第一个文本框时按 Tab 键
- 在第一个文本框上触发按键按下事件
- 将焦点移至第二个文本框
- 将手指从 Tab 键上抬起
- Keyup 事件在第二个文本框上触发
Key up is fired for the second text box because that is where it occurs since the focus was shifted to that input.
为第二个文本框触发向上键,因为自从焦点转移到该输入后,它就出现在那里。
You can't prevent this sequence of events from happening, but you could inspect the event to see what key was pressed, and call preventDefault()
if it was the tab key.
您无法阻止这一系列事件的发生,但您可以检查事件以查看按下了哪个键,并调用preventDefault()
它是否是 Tab 键。
回答by KyleMit
I was recently dealing with this for a placeholder polyfill. I found that if you want to capture the keyup event in the originating field, you can listen to the keydown event and fire the keyup event if a tab was pressed.
我最近正在处理这个占位符 polyfill。我发现如果您想在原始字段中捕获 keyup 事件,您可以监听 keydown 事件并在按下选项卡时触发 keyup 事件。
Instead of this:
取而代之的是:
$(this).on({'keyup': function() {
//run code here
}
});
Change to this:
改成这样:
$(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
}
});