Javascript jQuery 处理焦点和单击元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4889355/
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
jQuery handing both focus and click on an element
提问by Clinton Pierce
I'm trying to determine workflow to fine-tune a data entry web application. Picture several address forms on a single web page:
我正在尝试确定工作流以微调数据输入 Web 应用程序。在单个网页上描绘多个地址表格:
1. Name___________
Street_________
Phone__________
2. Name___________
Street_________
Phone__________
[...many more...]
Now I'd like to know if the user is using the tab key to get to the second "Name" field (or anywhere within that record), or if they're using the mouse to click on it. (Or shift-tab to move in reverse.)
现在我想知道用户是否使用 Tab 键进入第二个“名称”字段(或该记录中的任何位置),或者他们是否使用鼠标单击它。(或 shift-tab 反向移动。)
I've set a handler on both focus and click for the input fields:
我在输入字段的焦点和单击上都设置了一个处理程序:
$('input').click(function() { TabulateClick(this) });
$('input').focus(function() { TabulateFocus(this) });
And in the handler, I determine which address the user is working on and whether we've "switched" Address records. (If the focus was in "Phone" for the first address, and you click on the "Name" field in the same address, that's not actually switching records, so I don't tabulate that.)
在处理程序中,我确定用户正在处理哪个地址以及我们是否“切换”了地址记录。(如果焦点位于第一个地址的“电话”中,并且您单击同一地址中的“姓名”字段,则实际上并没有切换记录,因此我不会将其制成表格。)
function TabulateClick(field)
{
var currentAddressRecord = FindAddress(field);
if ( lastAddressRecord != currentAddressRecord )
switchedAddressesWithClick++;
lastAddressRecord = currentAddress;
}
function TabulateFocus(field)
{
var currentAddress = FindAddress(field);
if ( lastAddressRecord != currentAddressRecord )
switchedAddressesWithTab++;
lastAddressRecord = currentAddress;
}
My problem is that when I mouse-click into the field the focus
event fires first tabulating a false switchedAddressesWithTab
and changing the currentAddress (that's bad). When the click
handler runs, the lastAddressRecord
is spoiled.
我的问题是,当我用鼠标单击该字段时,该focus
事件首先触发一个 falseswitchedAddressesWithTab
并更改 currentAddress(这是不好的)。当click
处理程序运行时,lastAddressRecord
被宠坏了。
Is there a way inside of the focus
handler to know that there is a pending click
event on the same object? Or in the click
handler to know that it was previously just handled by focus
?
focus
处理程序内部有没有办法知道click
同一个对象上有挂起的事件?或者在click
处理程序中知道它以前只是由focus
?
回答by Juan Mendes
Here's something that I think works based on the fact that the mousedown happens before the focus. See demo.
这是我认为基于鼠标按下发生在焦点之前的事实。见演示。
var lastClick = null;
$('input').mousedown(function(e) {
lastClick = e.target;
}).focus(function(e){
if (e.target == lastClick) {
console.log('click');
} else {
console.log('tab');
}
lastClick = null;
});
To fix the bug discovered by Josiah, I changed my code to the below. See demo.
为了修复 Josiah 发现的错误,我将代码更改为以下内容。见演示。
var lastFocusedElement = null;
var isClick = false;
$('input').mousedown(function(e) {
isClick= true;
}).focus(function(e){
// To prevent focus firing when element already had focus
if (lastFocusedElement != e.target) {
if (isClick) {
console.log('click ----');
} else {
console.log('tab -----');
}
lastFocusedElement = e.target;
isClick = false;
}
});
$(document.body).focus(function(){
lastFocusedElement = document.body;
});
The one problem is that you don't get 'click' or tab when you switch away from the window and switch back. You get a focus event on the input that had focus, but you can't determine if it's a tab or a click, because it's neither.
一个问题是当您离开窗口并切换回来时,您不会得到“单击”或选项卡。您会在具有焦点的输入上获得焦点事件,但您无法确定它是选项卡还是单击,因为两者都不是。
I think this is the closest you'll get, I would try this on your page and see if the behavior is good enough.
我认为这是您最接近的,我会在您的页面上尝试这个,看看行为是否足够好。
回答by Nima Foladi
You could use the .on()method in jQuery. Here is another way to bind both events on the same element.
您可以在 jQuery 中使用.on()方法。这是在同一元素上绑定两个事件的另一种方法。
var hasClicked = false;
$('.myinputfield').on('mousedown : click',function(e){
if (e.type == 'mousedown') {
// execute code
hasClicked = true;
}
if(e.type == 'focus' && !hasClicked) {
//execute code
console.log(e.type)
}
hasClicked = false;
});
回答by Josiah Ruddell
Just bind the focus and then check the event to see if e.which == 9 // tab
.
只需绑定焦点,然后检查事件以查看e.which == 9 // tab
.
My original idea did not work (thanks @Juan). Using the combination of events should get you where you want to be. If the user clicks into the text box the last key press will not be a tab. All inputs are watching and storing the last key code to pass to the focus event. here is the fiddle
我最初的想法不起作用(感谢@Juan)。使用事件的组合应该可以让你到达你想要的地方。如果用户单击文本框,最后一次按下的键将不是选项卡。所有输入都在监视并存储要传递给焦点事件的最后一个键代码。 这是小提琴
var lastKeyCode = 0;
$('input').focus(function(e) {
if(lastKeyCode == 9)
// tabbed into field
else
// clicked into field
}).keydown(function(e){
if(e.which == 9) // added timeout to clear lastkeypress
setTimeout(function(){lastKeyPress = 0}, 50);
lastKeyPress = e.which; // store last key code
});