Question

How is this done?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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

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 source code for defining the custom event here.

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!

If this is for a button submitting a form (which is not necessarily the case for the original poster, but may be the case for other people getting here via Google), an easier option would be to disable the element that is being clicked on in your click event handler:

$(selector).click(function(e) {
    $(this).prop('disable', true);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top