jQuery处理焦点并单击元素

时间:2011-02-03 17:18:29

标签: javascript jquery events focus mouse

我正在尝试确定微调数据输入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处理?

3 个答案:

答案 0 :(得分:15)

我觉得这是基于mousedown发生在焦点之前的事实。请参阅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;

});

要修复Josiah发现的错误,我将代码更改为以下内容。请参阅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;
});

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

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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

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

我最初的想法没有用(感谢@Juan)。使用事件组合可以让您到达目的地。 如果用户单击文本框,则最后一次按键将不是选项卡。所有输入都在观察并存储最后一个密钥代码以传递给焦点事件。 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
});