Reputation: 5374
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?
Upvotes: 62
Views: 73265
Reputation: 10920
A modern approach using ES6
document.addEventListener('keyup', function (e) {
const $inputElementInQuestion = document.getElementById('foo');
if (e.key === "Tab" && document.activeElement === $inputElementInQuestion {
//do something
}
});
Upvotes: 0
Reputation: 58422
Update: 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!');
}
});
Original: 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!');
}
});
});
Upvotes: 57
Reputation: 2509
I use the following:
(function() {
const tabHistory = [];
window.addEventListener('keyup', function (e) {
const code = e.keyCode || e.which;
const index = tabHistory.length === 0 ? 1 : tabHistory.length + 1;
if (code == 9) {
tabHistory.push({
element: e.target,
index
});
console.log(index, e.target, tabHistory);
}
});
})();
I recommend keeping a track of the focused elements, this way you make sure the user will be able to tab as you expected.
Hope it helps!
Upvotes: 2
Reputation: 664
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:
Upvotes: 13
Reputation: 5
You can check focus event on specific input by this code
$(window).on('keyup', function(event){
if(event.keyCode == '9'){
getFocused(event);
}
})
var focused = 0;
function getFocused(e){
var ida = $(':focus').eq(0).prop('id');
if(ida=='detect' && focused==0){
focused = 1;
console.log(e);
}
}
Upvotes: 0
Reputation: 129792
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.
Upvotes: 1