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?

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




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

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){
    //code for keydown
    //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;
   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!


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.