+13  A: 

This is a good question, and I actually don't think it can be done easily. (Some discussion on this)

If it is super duper important for you to have this functionality, you could hack it like so:

function singleClick(e) {
    // do something, "this" will be the DOM element
}

function doubleClick(e) {
    // do something, "this" will be the DOM element
}

$(selector).click(function(e) {
    var that = this;
    setTimeout(function() {
        var dblclick = parseInt($(that).data('double'), 10);
        if (dblclick > 0) {
            $(that).data('double', dblclick-1);
        } else {
            singleClick.call(that, e);
        }
    }, 300);
}).dblclick(function(e) {
    $(this).data('double', 2);
    doubleClick.call(this, e);
});

And here is an example of it at work.

As pointed out in the comments, there is a plugin for this that does what I did above pretty much, but packages it up for you so you don't have to see the ugly: FixClick.

Paolo Bergantino
Well it appears to work, but it has the distinct problem of not detecting regular clicks for .5 seconds. I could shorten the time, of course, but... oh well. I'll figure this out then myself. Thanks anyway.
Daddy Warbox
Yeah, I'm thinking 250 or even less is probably reasonable to expect as far as double clicks go. I've been doing some serious googling on this and apparently this is the best you're gonna get. I could make a plugin out of it to hide the ugly away if it makes you feel better. :)
Paolo Bergantino
Interesting, hadn't tried this yet and indeed looks like a hackish way to do it. But from an event -point-of-view it makes sense that the click-event gets called twice
jitter
Actually, couldn't I simply block subsequent single click events during the double-click duration? I think that'd solve the delay problem.
Daddy Warbox
Btw there already seems to be a plugin for this http://plugins.jquery.com/project/FixClick which solves it similar to Paolo Bergantino
jitter
Nice find, jitter. Looking at the source code they are doing essentially what I am doing, but they went for a 300ms default timer. That sounds reasonable.
Paolo Bergantino
For what it's worth, here is the source for another plugin which does this (mentioned one of the other answers) which uses custom/special events:http://bit.ly/diBCkI
balupton
+3  A: 

The technique outlined in the other answers is known as debouncing.

wrumsby
Cool stuff and nice article. +1
Paolo Bergantino
+8  A: 

Raymond Chen has discussed some of the implications of single-versus-double clicking - although he's talking in the context of Windows, what he says is relevant to browser-based UI design.

Basically, the action taken on a double click should be a logical thing to do after a single click. So for example, in a desktop UI, single click selects an item, and double click opens it (e.g. opens the file, or launches the application). The user would have to select the file to open it anyway, so it doesn't matter that the single click action is taken before the double click action.

If you have a UI component whose double click action is completely unrelated to the single click action, such that it becomes necessary to prevent the single click action from occurring once the system realises it was actually a double click, then you really ought to rethink your design. Users will find it awkward and counter-intuitive, in that it will not act in the way they are used to things acting.

If you still want to go that way, then you will either have to use the debouncing technique (in which case all single click actions will be delayed) or else implement some mechanism whereby the double click handler undoes the work done by the single click handler.

You should also be aware that some users set a very long double click time. Somebody with, for example, arthritic hands might have a double click time of more than a second set in their system preferences, so the debouncing technique based on some arbitrary time period of your choosing is going to make your UI component inaccessible to those people if taking the single click action precludes taking the double click action. The "undo what just happened on single click" technique is the only viable workaround for this, as far as I know.

NickFitz
these are good points!
DustMason
A: 

jQuery Sparkle provides a clean elegant solution for this, by implementing a singleclick custom event. By doing this, you can use it just like any other event, so:

$('#el').singleclick(function(){});
// or event
$('#el').bind('singleclick', function(){});

It also provides custom events for the last and first clicks of a series of clicks. And the lastclick custom event actually passes the amount of clicks back! So you could do this!

$('#el').lastclick(function(event,clicks){
    if ( clicks === 3 ) alert('Tripple Click!');
});

You can find the appropriate demo showcasing what I've just said right here: http://www.balupton.com/projects/jquery-sparkle/#event-singleclick

And the source code for defining the custom event right here: http://bit.ly/diBCkI

It's open source under the AGPL licence, so you can feel free to grab what you need out of it worry free! :-) It's also actively developed on a day to day basis so you will never be short on support.

But most importantly it is a DRY Plugin/Effect Framework to allow you to develop plugins and extensions much more easily. So hope this helps to achieve that goal!

You can find more about jQuery Sparkle, and see some demos of it right here at it's homepage: http://www.balupton.com/projects/jquery-sparkle

Hope I've helped!

balupton