简体   繁体   English

jQuery处理焦点并单击元素

[英]jQuery handing both focus and click on an element

I'm trying to determine workflow to fine-tune a data entry web application. 我正在尝试确定微调数据输入Web应用程序的工作流程。 Picture several address forms on a single web page: 在单个网页上显示几个地址表单:

  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. 现在我想知道用户是否正在使用tab键进入第二个“Name”字段(或该记录中的任何位置),或者他们是否使用鼠标点击它。 (Or shift-tab to move in reverse.) (或移位标签反向移动。)

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 ). 我的问题是,当我鼠标点击进入该字段时, focus事件首先会触发一个假的switchedAddressesWithTab并更改当前地址(这是坏的 )。 When the click handler runs, the lastAddressRecord is spoiled. click处理程序运行时, lastAddressRecord被破坏。

Is there a way inside of the focus handler to know that there is a pending click event on the same object? focus处理程序内部是否有一种方法可以知道同一对象上存在挂起的click事件? Or in the click handler to know that it was previously just handled by focus ? 或者在click处理程序中知道它以前只是由focus处理?

Here's something that I think works based on the fact that the mousedown happens before the focus. 这是我认为基于mousedown发生在焦点之前的事实。 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. 为了解决Josiah发现的错误,我将代码更改为以下内容。 See demo . 演示

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. 我认为这是你最接近的,我会在你的页面上尝试这个,看看行为是否足够好。

You could use the .on() method in jQuery. 你可以在jQuery中使用.on()方法。 Here is another way to bind both events on the same element. 这是在同一元素上绑定两个事件的另一种方法。

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

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). 我最初的想法没有用(感谢@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 这是小提琴

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM