views:

59

answers:

2

What's the best way to execute a function exactly once every time a button is clicked, regardless of click speed and browser?

Simply binding a "click" handler works perfectly in all browsers except IE.

In IE, when the user clicks too fast, only "dblclick" fires, so the "click" handler is never executed. Other browsers trigger both events so it's not a problem for them.

The obvious solution/hack (to me at least) is to attach a dblclick handler in IE that triggers my click handler twice. Another idea is to track clicks myself with mousedown/mouseup, which seems pretty primitive and probably belongs in a framework rather than my application.

So, what's the best/usual/right way of handling this? (pure javascript or jQuery preferred)

+1  A: 

Depending on your situation you can use different approaches, but I would suggest using namespaced event handlers with jQuery like this:

function eventHandler(event) {
    // your handler code here
    doSomeMagic();
}

var element = $('#element');

element.one('click.someNameSpace', function(event){
    // first we unbind all other event handlers with this namespace
    element.unbind('.someNameSpace');

    // then we execute our eventHandler
    eventHandler();
}).one('dblclick.someNameSpace',  function(event){
    // If this fires first, we also unbind all event handlers
    element.unbind('.someNameSpace');

    // and then execute our eventHandler
    eventHandler();
});

I'm not sure this will work the way you want it, but it's a start, I guess.

Igor Zinov'yev
looks interesting, never used namespaced events, thanks!It is SO useful, wonder why i missed in reading jq doc
vittore
+1  A: 

Mousedown and mouseup works just like the click functions, unfortunately so much that when IE omits a click because of a doubleclick it will also omit the mousedown and mouseup. In any case, you can add both click and dblclick to the same object and feed the clicks through a function that sort out any click happening too close to the last.

<div onclick="clk()" ondblclick="clk()"></div>

lastclicktime=0
function clk(){
    var time=new Date().getTime()
    if(time>lastclicktime+50){
        lastclicktime=time
        //Handle click
    }
}

I by the way just found out that, at least in Firefox the dblclick event is not given an event time, therefore I had to resolve to the Date method.

eBusiness