Detect focus initiated by tab key?

60,017

Solution 1

I know you have accepted an answer but you could test the button pressed using the following:

$('#detect').on('focus', function(e){
    $(window).keyup(function (e) {
        var code = (e.keyCode ? e.keyCode : e.which);
        if (code == 9) {
           alert('I was tabbed!');
        }
    });
});

http://jsfiddle.net/LPGLm/1/

Edit: change the listener around:

$(window).keyup(function (e) {
    var code = (e.keyCode ? e.keyCode : e.which);
    if (code == 9 && $('#detect:focus').length) {
        alert('I was tabbed!');
    }
});

http://jsfiddle.net/LPGLm/7/

Solution 2

A more responsive solution would be to use two listeners:

var mousedown = false;
$('#detect').on('mousedown', function () {
    mousedown = true;
});

$('#detect').on('focusin', function () {
    if(!mousedown) {
        // logic
    }
    mousedown = false;
});

Fiddle showing the difference in speed:

http://jsfiddle.net/u2y45/1/

Solution 3

As you've noticed, the event object itself does not distinguish the means of access. What you can do is to bind a mousedown listener, which will fire before focus, and set some timestamp flag that you compare to some threshold value in your focus handler.

Share:
60,017
HellaMad
Author by

HellaMad

Updated on July 09, 2022

Comments

  • HellaMad
    HellaMad almost 2 years

    I want to detect the focus event of an element, but only if it was initiated by the user pressing the tab key. For example:

    <input type="text" id="foo" />
    <input type="text" id="detect" />
    

    If the user is focused on #foo and presses Tab, I want the event to fire once #detect becomes focused (or a conditional inside the focus event to be true). Conversely, if the user simply clicks on the #detect field to focus it, I do not want the event to fire (or I want the conditional inside the focus event call to be false).

    I don't want to use the keydown event of #foo and check if the tab key was pressed, as I want the approach to be independent of any other element.

    I looked through the console output of the following code, but couldn't notice any real differences between the two methods of focusing:

    $('#detect').on('focus', function(e){
       console.log(e); 
    });
    

    (fiddle)

    Is this possible to accomplish in a relatively simple way?

  • HellaMad
    HellaMad about 11 years
    Hmmm, that's actually pretty clever. Didn't think of that, thanks.
  • David Hedlund
    David Hedlund about 11 years
    Note that this distinguishes between tab and click, but it will not help you distinguish tab from .focus(), but then I don't know if that's somethin you want. If you do want that, perhaps you could implement a global keyup listener for tab and compare the proximity between the latest tab and your focus event, but that seems... arduous.
  • HellaMad
    HellaMad about 11 years
    It does indeed seem arduous. I'm not worried about .focus() triggering my event, so everything should work as you originally pointed out. Thanks again!
  • HellaMad
    HellaMad about 11 years
    Hm, this actually seems like a better solution.. I unselected the answer, I'll hold off on selecting for now.
  • David Hedlund
    David Hedlund about 11 years
    You might be on to something, but you're not there. Every time #detect gains focus, a global event listener will be registered, that looks for a tab anywhere. So if focus and blur #detect three times by clicking in and outside it, blur it, and then hit tab so that #foo gains focus, you'll still get three "I was tabbed" alerts.
  • Pete
    Pete about 11 years
    Have changed the answer for a better way to do it