Differentiate between mouse and keyboard triggering onclick
Solution 1
You can create a condition with event.type
function submitData(event, id)
{
if(event.type == 'mousedown')
{
// do something
return;
}
if(event.type == 'keypress')
{
// do something else
return;
}
}
Note: You'll need to attach an event which supports both event types. With JQuery it would look something like $('a.save').bind('mousedown keypress', submitData(event, this));
The inline onClick=""
will not help you as it will always pass that click event since that's how it's trapped.
EDIT: Here's a working demo to prove my case with native JavaScript: http://jsfiddle.net/AlienWebguy/HPEjt/
I used a button so it'd be easier to see the node highlighted during a tab focus, but it will work the same with any node.
Solution 2
Could check if event.screenX
and event.screenY
are zero.
$('a#foo').click(function(evt) {
if (evt.screenX == 0 && evt.screenY == 0) {
window.alert('Keyboard click.');
} else {
window.alert('Mouse click.');
}
});
I couldn't find a guarantee that it works in all browsers and all cases, but it has the benefit of not trying to detect a "click" done via the keyboard. So this solution detects "click" more reliably at the cost of detecting if it's from keyboard or mouse somewhat less reliably. If you prefer the reverse, look as the answer from @Gonzalo.
Note: One place I found using this method is Chromium
Solution 3
You can use event.detail
if(event.detail === 0) {
// keypress
} else {
// mouse event
}
Solution 4
You can differentiate between a click and a keyboard hit capturing and discarding the keydown event originated at the moment of the key press:
jQuery(function($) {
$("a#foo").keydown(function() {
alert("keyboard");
return false;
}).click(function() {
alert("mouse");
return false;
})
})
Solution 5
I use the following
const isKeyboardClick = nativeEvent.detail === 0 && !nativeEvent.pointerType;
Works in evergreen browsers via detail
and IE11 via pointerType
. Does not work for the case where e.g. radio button <input>
is wrapped by a <label>
element.
Comments
-
Craig over 2 years
I need to find a way to determine if a link has been activated via a mouse click or a keypress.
<a href="" onclick="submitData(event, '2011-07-04')">Save</a>
The idea is that if they are using a mouse to hit the link then they can keep using the mouse to choose what they do next. But if they tabbing around the page and they tab to the Save link, then I'll open then next line for editing (the page is like a spreadsheet with each line becoming editable using ajax).
I thought the event parameter could be queried for which mouse button is pressed, but when no button is pressed the answer is 0 and that's the same as the left mouse button. They I thought I could get the keyCode from the event but that is coming back as undefined so I'm assuming a mouse event doesn't include that info.
function submitData(event, id) { alert("key = "+event.keyCode + " mouse button = "+event.button); }
always returns "key = undefined mouse button = 0"
Can you help?
-
mu is too short over 12 yearsI'm seeing an
event.type
of "click" in both cases. -
Craig over 12 yearsThis worked for me. Since the save button only gets rendered if the row has become editable I'll look into jQuery Live for hooking up the mousedown and keypress events. Cheers.
-
Ben over 11 years+1 Excellent! This is not just the most elegant answer, but really the only actual working answer to the question that preserves the meaning of the "click" concept. The other answers switch out click (the original question) for either mousedown or mouseup, which are only part of a click. Nobody wants a mouseup that began as a mousedown on a different element to be handled as a click. Nice!
-
Ben over 11 yearsCool, but this doesn't really answer the question. A mousedown is not a click. This is a workaround that perverts the meaning of a click, which is a mousedown followed by a mouseup on the same element. Gonzalo's solution preserves the meaning of the concept.
-
Wernight over 8 yearsIt doesn't take "click" behavior into account. A click is mouse down and mouse up on same item, handling also long touch or drag touch on touch-sensitive devices, handling also various keyboard "clicks".
-
Wernight over 8 yearsThere are various ways to "click" from keyboard. Usually its [ctrl+][alt+]enter but many of those open in a new tab so that should remain consistent, and sometimes other keyboard shortcuts.
-
Roman Royter almost 8 yearsThis doesn't work with "Enter" key. It fires both events sequentially.
-
SimplGy over 5 yearsClever. This is the only working solution on the page as of Sep 2018
-
Prid almost 5 yearsalmost perfect. Doesn't work for Bootstrap 4 radio buttons, as when the active radio button is Mouse-clicked twice, two events are triggered (one for the aesthetic button label, and one for the input radio button behind). The first one (for <label>) returns
event.detail === 1
as expected, but the second one (for <input radio>) returnevent.detail === 0
, probably because Bootstrap is handling the change in background. +1 for promising answer, and it'll work in most cases :) -
lenny over 4 years@Prid maybe you can figure out a workaround using
event.stopPropagation
? I'm not sure whether the label always fires even when you click directly on the radio button. -
Craig Kovatch over 4 yearsDoesn't work in Safari, though. Safari defaults the screen coordinates to the center of the target element. :(
-
Craig Kovatch over 4 yearsIE11 event.detail is 0 for both mouse and keyboard click events :(
-
Jussi Virtanen almost 4 yearsI had used this method too, but after @CraigKovatch's comment about Safari I noticed that that's indeed the case: it doesn't work on Safari (v13.1.1).
-
Mingwei Samuel almost 3 years
mousedown
is not the same asclick
(although it may be close enough in some situations) -
terryoboy almost 2 yearsAs of 2022, this is still the only working solution. At least in this thread. All ENTER, ARROW DOWN, and MOUSE CLICK events trigger the same
evt.type
value ofclick
.