I have this sample code:
$myTrigger
.click(function(e){
alert('click');
})
.focus(function(e){
alert('focus');
$(this).click()
})
The intent is that I want something to happen when you click on $myTrigger. If, on the other hand, you tab onto it via the keyboard (ie, focus) I want the exact same thing to happen, so I ask it to click.
The catch is if I click on it, it also focuses. So both alerts are going off.
Is there a way to prevent the focus event from going off when clicking?
UPDATE:
Ajm's comment got me thinking that I'm maybe asking the wrong thing.
Question: Does a click event always also trigger focus in javascript (and/or in jQuery?). Can I assume whenever I want to handle both clicking with the mouse and tabbing-in with the keyboard, the focus() event will handle both?
Or is it dependent on the particular element that I'm attaching the events to? (In this case $myObject happens to be an anchor tag (link).
jQuery has a built-in functon for this that's not used all that often called .one()
$mytrigger.one('click focus', function() { alert("event"); });
This will only trigger once, or you can re-bind if you want afterwards.
To trigger click() for TAB focus (and prevent click() from being triggered twice when focus comes from a mouse click), I did the following:
$('#item').mousedown(function(){
$(this).data("mouseDown", true);
});
$('#item').mouseup(function(){
$(this).removeData("mouseDown");
});
$('#item').focus(function(){
if (!$(this).data("mouseDown"))
$(this).click();
});
Does that work good for you?
Another option is:
$myTrigger
.mousedown(function(e) {
e.preventDefault(); // don't grab focus
})
.click(function(e) {
alert('click');
})
.focus(function(e) {
alert('focus');
$(this).click()
});
This will leave the keyboard focus wherever it was before when clicking the button, while still allowing the button to become focused via Tab (or programmatically calling .focus()
on it).
I ran into a similar problem a while back. I solved it by responding to the first event, and ignoring events for the next 20ms.
Try something like this:
$(document).ready(OnReady);
var okToClick = true;
function OnReady() {
//Attach to both click and focus events
$("#item").click(PerformAction).focus(PerformAction);
}
function PerformAction() {
if (okToClick) {
okToClick = false;
// Do something interesting here...
setTimeout(function() { okToClick = true; }, 20);
}
}
You can use only the focus() method and read this article about events (e) types on JavaScript: http://www.quirksmode.org/js/events_properties.html
To detect what event you got with you mouse or keyboard (to test it), u can use:
if (!e) var e = window.event;
alert(e.type);
To prevent focus from being called twice set a variable to tell if the element has focus.
var hasFocus = false;
$('#myTrigger').focusIn(
function(){
hasFocus = true;
//do stuff
}
);
$('#myTrigger').focusOut(
function(){
hasFocus = false;
}
);
Put all functionality on focus and tell jQuery to set the foucus on the element when it is clicked if you run into a browser which doesn't do that.
$(#myTrigger).click( function(){ if(!hasFocus){$(#myTrigger).focus()}});
来源:https://stackoverflow.com/questions/2458109/jquery-trigger-action-on-focus-or-click-but-not-both