简体   繁体   中英

Differentiate between focus event triggered by keyboard/mouse

I'm using jquery ui autocomplete and want to decipher between focus events triggered by keyboard interaction and mouse interaction. How would I go about this?

$('input').autocomplete({
    source: function(request, response) {
        ...
    },
    focus: function(event, ui) {
        // If focus triggered by keyboard interaction
            alert('do something');
        // If focus event triggered by mouse interaction
            alert('do something else');
    }
});

Thanks

The only way I can think of doing this is to have a handler listen in on the keypress and click events, and toggle a boolean flag on/off. Then on the focus handler of your input, you can just check what the value of your flag is, and go from there.

Probably something like

var isClick;
$(document).bind('click', function() { isClick = true; })
           .bind('keypress', function() { isClick = false; })
           ;

var focusHandler = function () {
    if (isClick) {
        // clicky!
    } else {
        // tabby!
    }
}

$('input').focus(function() {
    // we set a small timeout to let the click / keypress event to trigger
    // and update our boolean
    setTimeout(focusHandler,100);
});

Whipped up a small working prototype on jsFiddle (don't you just love this site?). Check it out if you want.

Of course, this is all running off a focus event on an <input> , but the focus handler on the autocomplete works in the same way.

The setTimeout will introduce a bit of lag, but at 100ms, it might be negligible, based on your needs.

You should actually be able to determine this from the event-Object that is passed into the focus-event. Depending on your code structure this might be different, but there is usually a property called originalEvent in there, which might be nested to some depth. Examine the event -object more closely to determine the correct syntax. Then test on mousenter or keydown via regular expression. Something like this:

focus: function(event, ui){
  if(/^key/.test(event.originalEvent.originalEvent.type)){
    //code for keydown
  }else{
    //code for mouseenter and any other event
  }
}

The easiest and most elegant way I've found of achieving this is to use the " What Input? " library. It's tiny (~2K minified), and gives you access to the event type both in scripts:

if (whatInput.ask() === 'mouse') {
  // do something
}

...and also (via a single data attribute that it adds to the document body ) styles:

[data-whatinput="mouse"] :focus,
[data-whatinput="touch"] :focus {
  // focus styles for mouse and touch only
}

I particularly like the fact that where you just want a different visual behaviour for mouse / keyboard it makes it possible to do that in the stylesheet (where it really belongs) rather than via some hacky bit of event-checking Javascript (though of course if you do need to do something that's not just purely visual, the former approach lets you handle it in Javascript instead).

The first thing that comes to mind is that you can find the position of the mouse and check to see if its within the position of the element

Use this to store the position of the element:

var input = $('#your_autocompleted_element_id'),
    offset = input.offset(),
    input_x = offset.top,
    input_y = offset.left,
    input_w = input.outerWidth(),
    input_h = input.outerHeight();

Then use this to find absolute position of the mouse within the window:

var cur_mx, cur_my;
$(document).mousemove(function(e){
   cur_mx = e.pageX;
   cur_my = e.pageY;
});

Then in your autcomplete setup:

focus: function(event, ui) {
   // mouse is doing the focus when...
   // mouse x is greater than input x and less than input x + input width
   // and y is greater than input y and less than input y + input height
   if (cur_mx >= input_x && cur_mx <= input_x + input_w && cur_my >= input_y && cur_my <= input_y + input_h) {
      // do your silly mouse focus witchcraft here
   } else {
      // keyboard time!
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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