Jquery 绑定双击和单击分开

在 jquery 中是否有什么东西可以让我区分双击和单击的行为?

当我将两个元素绑定到同一个元素时,只执行单击操作。

有没有办法在执行单击之前等待一段时间,看看用户是否再次单击?

谢谢:)

107390 次浏览

You could probably write your own custom implementation of click/dblclick to have it wait for an extra click. I don't see anything in the core jQuery functions that would help you achieve this.

Quote from .dblclick() at the jQuery site

It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable.

Sure, bind two handlers, one to click and the other to dblclick. Create a variable that increments on every click. then resets after a set delay. Inside the setTimeout function you can do something...

var DELAY = 2000,
clicks = 0,
timer = null;


$('a').bind({
click: function(e) {
clearTimeout(timer);


timer = setTimeout(function() {
clicks = 0;
}, DELAY);


if(clicks === 1) {
alert(clicks);
//do something here


clicks = 0;
}


//Increment clicks
clicks++;
},
dblclick: function(e) {
e.preventDefault(); //don't do anything
}
});

I found that John Strickler's answer did not quite do what I was expecting. Once the alert is triggered by a second click within the two-second window, every subsequent click triggers another alert until you wait two seconds before clicking again. So with John's code, a triple click acts as two double clicks where I would expect it to act like a double click followed by a single click.

I have reworked his solution to function in this way and to flow in a way my mind can better comprehend. I dropped the delay down from 2000 to 700 to better simulate what I would feel to be a normal sensitivity. Here's the fiddle: http://jsfiddle.net/KpCwN/4/.

Thanks for the foundation, John. I hope this alternate version is useful to others.

var DELAY = 700, clicks = 0, timer = null;


$(function(){


$("a").on("click", function(e){


clicks++;  //count clicks


if(clicks === 1) {


timer = setTimeout(function() {


alert("Single Click");  //perform single-click action
clicks = 0;             //after action performed, reset counter


}, DELAY);


} else {


clearTimeout(timer);    //prevent single-click action
alert("Double Click");  //perform double-click action
clicks = 0;             //after action performed, reset counter
}


})
.on("dblclick", function(e){
e.preventDefault();  //cancel system double-click event
});


});
var singleClickTimer = 0; //define a var to hold timer event in parent scope
jqueryElem.click(function(e){ //using jquery click handler
if (e.detail == 1) { //ensure this is the first click
singleClickTimer = setTimeout(function(){ //create a timer
alert('single'); //run your single click code
},250); //250 or 1/4th second is about right
}
});


jqueryElem.dblclick(function(e){ //using jquery dblclick handler
clearTimeout(singleClickTimer); //cancel the single click
alert('double'); //run your double click code
});

This solution works for me

var DELAY = 250, clicks = 0, timer = null;


$(".fc-event").click(function(e) {
if (timer == null) {
timer = setTimeout(function() {
clicks = 0;
timer = null;
// single click code
}, DELAY);
}


if(clicks === 1) {
clearTimeout(timer);
timer = null;
clicks = -1;
// double click code
}
clicks++;
});

I made some changes to the above answers here which still works great: http://jsfiddle.net/arondraper/R8cDR/

i am implementing this simple solution , http://jsfiddle.net/533135/VHkLR/5/
html code

<p>Click on this paragraph.</p>
<b> </b>

script code

var dbclick=false;
$("p").click(function(){
setTimeout(function(){
if(dbclick ==false){
$("b").html("clicked")
}


},200)


}).dblclick(function(){
dbclick = true
$("b").html("dbclicked")
setTimeout(function(){
dbclick = false




},300)
});


its not much laggy

(function($){


$.click2 = function (elm, o){
this.ao = o;
var DELAY = 700, clicks = 0;
var timer = null;
var self = this;


$(elm).on('click', function(e){
clicks++;
if(clicks === 1){
timer = setTimeout(function(){
self.ao.click(e);
}, DELAY);
} else {
clearTimeout(timer);
self.ao.dblclick(e);
}
}).on('dblclick', function(e){
e.preventDefault();
});


};


$.click2.defaults = { click: function(e){}, dblclick: function(e){} };


$.fn.click2 = function(o){
o = $.extend({},$.click2.defaults, o);
this.each(function(){ new $.click2(this, o); });
return this;
};


})(jQuery);

And finally we use as.

$("a").click2({
click : function(e){
var cid = $(this).data('cid');
console.log("Click : "+cid);
},
dblclick : function(e){
var cid = $(this).data('cid');
console.log("Double Click : "+cid);
}
});

Same as the above answer but allows for triple click. (Delay 500) http://jsfiddle.net/luenwarneke/rV78Y/1/

    var DELAY = 500,
clicks = 0,
timer = null;


$(document).ready(function() {
$("a")
.on("click", function(e){
clicks++;  //count clicks
timer = setTimeout(function() {
if(clicks === 1) {
alert('Single Click'); //perform single-click action
} else if(clicks === 2) {
alert('Double Click'); //perform single-click action
} else if(clicks >= 3) {
alert('Triple Click'); //perform Triple-click action
}
clearTimeout(timer);
clicks = 0;  //after action performed, reset counter
}, DELAY);
})
.on("dblclick", function(e){
e.preventDefault();  //cancel system double-click event
});
});

Look at the following code

$("#clickMe").click(function (e) {
var $this = $(this);
if ($this.hasClass('clicked')){
alert("Double click");
//here is your code for double click
return;
}else{
$this.addClass('clicked');
//your code for single click
setTimeout(function() {
$this.removeClass('clicked'); },500);
}//end of else
});

Demo goes here http://jsfiddle.net/cB484/

This is a method you can do using the basic JavaScript, which is works for me:

var v_Result;
function OneClick() {
v_Result = false;
window.setTimeout(OneClick_Nei, 500)
function OneClick_Nei() {
if (v_Result != false) return;
alert("single click");
}
}
function TwoClick() {
v_Result = true;
alert("double click");
}

I've written a jQuery plugin that allow also to delegate the click and dblclick events

// jQuery plugin to bind both single and double click to objects
// parameter 'delegateSelector' is optional and allow to delegate the events
// parameter 'dblclickWait' is optional default is 300
(function($) {
$.fn.multipleClicks = function(delegateSelector, clickFun, dblclickFun, dblclickWait) {
var obj;
if (typeof(delegateSelector)==='function' && typeof(clickFun)==='function') {
dblclickWait = dblclickFun; dblclickFun = clickFun; clickFun = delegateSelector; delegateSelector = null; // If 'delegateSelector' is missing reorder arguments
} else if (!(typeof(delegateSelector)==='string' && typeof(clickFun)==='function' && typeof(dblclickFun)==='function')) {
return false;
}
return $(this).each(function() {
$(this).on('click', delegateSelector, function(event) {
var self = this;
clicks = ($(self).data('clicks') || 0)+1;
$(self).data('clicks', clicks);
if (clicks == 1) {
setTimeout(function(){
if ($(self).data('clicks') == 1) {
clickFun.call(self, event); // Single click action
} else {
dblclickFun.call(self, event); // Double click action
}
$(self).data('clicks', 0);
}, dblclickWait || 300);
}
});
});
};
})(jQuery);

The solution given from "Nott Responding" seems to fire both events, click and dblclick when doubleclicked. However I think it points in the right direction.

I did a small change, this is the result :

$("#clickMe").click(function (e) {
var $this = $(this);
if ($this.hasClass('clicked')){
$this.removeClass('clicked');
alert("Double click");
//here is your code for double click
}else{
$this.addClass('clicked');
setTimeout(function() {
if ($this.hasClass('clicked')){
$this.removeClass('clicked');
alert("Just one click!");
//your code for single click
}
}, 500);
}
});

Try it

http://jsfiddle.net/calterras/xmmo3esg/

Below is my simple approach to the issue.

JQuery function:

jQuery.fn.trackClicks = function () {
if ($(this).attr("data-clicks") === undefined) $(this).attr("data-clicks", 0);


var timer;
$(this).click(function () {
$(this).attr("data-clicks", parseInt($(this).attr("data-clicks")) + 1);


if (timer) clearTimeout(timer);


var item = $(this);
timer = setTimeout(function() {
item.attr("data-clicks", 0);
}, 1000);
});
}

Implementation:

$(function () {
$("a").trackClicks();


$("a").click(function () {
if ($(this).attr("data-clicks") === "2") {
// Double clicked
}
});
});

Inspect the clicked element in Firefox/Chrome to see data-clicks go up and down as you click, adjust time (1000) to suit.

If you don't want to create separate variables to manage the state, you can check this answer https://stackoverflow.com/a/65620562/4437468