Javascript with jQuery: Click and double click on same element, different effect, one disables the other
The general idea:
Upon the first click, dont call the associated function (say single_click_function()). Rather, set a timer for a certain period of time(say x). If we do not get another click during that time span, go for the single_click_function(). If we do get one, call double_click_function()
Timer will be cleared once the second click is received. It will also be cleared once x milliseconds are lapsed.
BTW, check Paolo's reply out: Need to cancel click/mouseup events when double-click event detected and of course the entire thread! :-)
Better answer: https://stackoverflow.com/a/7845282/260610
Working demo
$('#alreadyclicked').val('no click');
$('td.dblclickable').on('click',function(){
var $button=$(this);
if ($button.data('alreadyclicked')){
$button.data('alreadyclicked', false); // reset
$('#alreadyclicked').val('no click');
if ($button.data('alreadyclickedTimeout')){
clearTimeout($button.data('alreadyclickedTimeout')); // prevent this from happening
}
// do what needs to happen on double click.
$('#action').val('Was double clicked');
}else{
$button.data('alreadyclicked', true);
$('#alreadyclicked').val('clicked');
var alreadyclickedTimeout=setTimeout(function(){
$button.data('alreadyclicked', false); // reset when it happens
$('#alreadyclicked').val('no click');
$('#action').val('Was single clicked');
// do what needs to happen on single click.
// use $button instead of $(this) because $(this) is
// no longer the element
},300); // <-- dblclick tolerance here
$button.data('alreadyclickedTimeout', alreadyclickedTimeout); // store this id to clear if necessary
}
return false;
});
obviously use <td class="dblclickable">
I wrote a simple jQuery plugin that lets you use a custom 'singleclick' event to differentiate a single-click from a double-click. This allows you to build an interface where a single-click makes the input editable while a double-click expands it. Much like Windows/OSX filesystem rename/open UI.
https://github.com/omriyariv/jquery-singleclick
$('#someInput').on('singleclick', function(e) {
// The event will be fired with a small delay but will not fire upon a double-click.
makeEditable(e.target);
}
$('#container').on('dblclick', function(e) {
// Expand the row...
}
Rewrite user822711's answer for reuse:
$.singleDoubleClick = function(singleClk, doubleClk) {
return (function() {
var alreadyclicked = false;
var alreadyclickedTimeout;
return function(e) {
if (alreadyclicked) {
// double
alreadyclicked = false;
alreadyclickedTimeout && clearTimeout(alreadyclickedTimeout);
doubleClk && doubleClk(e);
} else {
// single
alreadyclicked = true;
alreadyclickedTimeout = setTimeout(function() {
alreadyclicked = false;
singleClk && singleClk(e);
}, 300);
}
}
})();
}
Call the function.
$('td.dblclickable').bind('click', $.singleDoubleClick(function(e){
//single click.
}, function(e){
//double click.
}));
The issue only occurs when the editable field is clicked, so attach a regular click
handler to that element which will cancel propagation of the event (see stopPropagation
) and will set a timeout (setTimeout(...)
) for, say, 600ms (default time between two clicks to be deemed a dbl-click is 500ms [src]). If, by that time the dblclick
has not occurred (you can have a var accessible in both event handlers that acts as a flag to detect this) then you can assume the user wants to expand the row instead and continue with that action...
IMO, you should re-think this. Alas, a single click handler cannot know if the user is about to double-click.
I suggest making both actions single click, and simply don't propagate up from the editable field when it is clicked.