jQuery处理焦点并单击元素

我正在尝试确定微调数据输入Web应用程序的工作流程。 在单个网页上显示多个地址表单:

1. Name___________ Street_________ Phone__________ 2. Name___________ Street_________ Phone__________ [...many more...] 

现在我想知道用户是否正在使用tab键进入第二个“Name”字段(或该记录中的任何位置),或者他们是否使用鼠标点击它。 (或移位标签反向移动。)

我在焦点和点击输入字段上都设置了一个处理程序:

 $('input').click(function() { TabulateClick(this) }); $('input').focus(function() { TabulateFocus(this) }); 

在处理程序中,我确定用户正在处理哪个地址以及我们是否“切换”了地址记录。 (如果焦点位于第一个地址的“电话”中,并且您单击同一地址中的“名称”字段,那么实际上并没有切换记录,所以我没有将其列表。)

  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; } 

我的问题是,当我鼠标点击进入该字段时, focus事件首先会触发一个假的switchedAddressesWithTab并更改currentAddress(这是坏的 )。 click处理程序运行时, lastAddressRecord被破坏。

focus处理程序内部是否有一种方法可以知道同一对象上存在挂起的click事件? 或者在click处理程序中知道它以前只是由focus处理?

我认为这是基于mousedown发生在焦点之前的事实。 见演示 。

 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; }); 

为了解决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; }); 

一个问题是,当您从窗口切换并切换回来时,您不会获得“点击”或标签。 您在具有焦点的输入上获得焦点事件,但您无法确定它是标签还是单击,因为它既不是。

我认为这是你最接近的,我会在你的页面上尝试这个,看看行为是否足够好。

你可以在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; }); 

只需绑定焦点,然后检查事件以查看e.which == 9 // tab

我最初的想法没有用(感谢@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 });