How to run a function only once when it's triggered by both focus and click events

The best answer here would be to come up with a design that isn't trying to trigger the same action on two different events that can both occur on the same user action, but since you haven't really explained the overall problem you're coding, we can't really help you with that approach.

One approach is to keep a single event from triggering the same thing twice is to "debounce" the function call and only call the function from a given element if it hasn't been called very recently (e.g. probably from the same user event). You can do this by recording the time of the last firing for this element and only call the function if the time has been longer than some value.

Here's one way you could do that:

function debounceMyFunction() {
    var now = new Date().getTime();
    var prevTime = $(this).data("prevActionTime");
    $(this).data("prevActionTime", now);
    // only call my function if we haven't just called it (within the last second)
    if (!prevTime || now - prevTime > 1000) {
        callMyFunction();
    }
}

$(elem).focus(debounceMyFunction).click(debounceMyFunction);

You could use a timeout which get's cleared and set. This would introduce a slight delay but ensures only the last event is triggered.

$(function() {
  $('#field').on('click focus', function() {
    debounce(function() {
        // Your code goes here.
        console.log('event');
    });
  });  
});

var debounceTimeout;

function debounce(callback) {
  clearTimeout(debounceTimeout);
  debounceTimeout = setTimeout(callback, 500);
}

Here's the fiddle http://jsfiddle.net/APEdu/

UPDATE

To address a comment elsewhere about use of a global, you could make the doubleBounceTimeout a collection of timeouts with a key passed in the event handler. Or you could pass the same timeout to any methods handling the same event. This way you could use the same method to handle this for any number of inputs.


This worked for me:

http://jsfiddle.net/cjmemay/zN8Ns/1/

$('.button').on('mousedown', function(){
    $(this).data("mouseDown", true);
});

$('.button').on('mouseup', function(){
    $(this).removeData("mouseDown");
});

$('.button').on('focus', function(){
    if (!$(this).data("mouseDown"))
        $(this).trigger('click.click');
});

$(".button").on('click.click',evHandler);

Which I stole directly from this: https://stackoverflow.com/a/9440580/264498