如何区分单击事件和双击事件?

我在ID为"my_id" li中有一个button。 我用这个元素附加了two jquery事件

 1. $("#my_id").click(function() { alert('single click'); }); 2. $("#my_id").dblclick(function() { alert('double click'); }); 

但每次它给我一个single click

您需要使用超时检查第一次点击后是否有另一次点击。

诀窍是 :

 // Author: Jacek Becela // Source: http://gist.github.com/399624 // License: MIT jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) { return this.each(function(){ var clicks = 0, self = this; jQuery(this).click(function(event){ clicks++; if (clicks == 1) { setTimeout(function(){ if(clicks == 1) { single_click_callback.call(self, event); } else { double_click_callback.call(self, event); } clicks = 0; }, timeout || 300); } }); }); } 

用法:

 $("button").single_double_click(function () { alert("Try double-clicking me!") }, function () { alert("Double click detected, I'm hiding") $(this).hide() }) 
 <button>Click Me!</button> 

编辑:

如下所述,更喜欢使用本地dblclick事件: http : dblclick

或由jQuery提供的: http : //api.jquery.com/dblclick/

在Quirksmode中解释了dblclick事件的行为。

dblclick的事件顺序是:

  1. 鼠标按下
  2. 鼠标松开
  3. 点击
  4. 鼠标按下
  5. 鼠标松开
  6. 点击
  7. DBLCLICK

这个规则的一个例外是(当然)Internet Explorer与他们的自定义顺序:

  1. 鼠标按下
  2. 鼠标松开
  3. 点击
  4. 鼠标松开
  5. DBLCLICK

正如你所看到的,在同一个元素上同时监听两个事件会导致对你的click处理程序的额外调用。

一个简单的function。 没有jquery或其他框架是必需的。 传递你的函数作为参数

 <div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div> <script> function doubleclick(el, onsingle, ondouble) { if (el.getAttribute("data-dblclick") == null) { el.setAttribute("data-dblclick", 1); setTimeout(function () { if (el.getAttribute("data-dblclick") == 1) { onsingle(); } el.removeAttribute("data-dblclick"); }, 300); } else { el.removeAttribute("data-dblclick"); ondouble(); } } </script> 

恐怕这种行为依赖于浏览器:

将处理程序绑定到同一元素的click和dblclick事件是不可取的。 触发事件的顺序因浏览器而异,其中一些在dblclick之前接收到两个点击事件,而另一些事件则只有一个发生。 双击灵敏度(双击检测到的最大点击时间)可能因操作系统和浏览器而异,并且通常是用户可configuration的。

http://api.jquery.com/dblclick/

在Firefox中运行您的代码, click()处理程序中的alert()将阻止您再次单击。 如果你删除这样的警报,你会得到这两个事件。

那么为了双击(点击两次),你必须先点击一次。 click()处理程序会在您第一次点击时触发,并且由于popup警报,您没有机会再次单击来触发dblclick()处理程序。

改变你的处理程序做一些事情比alert() ,你会看到的行为。 (也许改变元素的背景颜色):

 $("#my_id").click(function() { $(this).css('backgroundColor', 'red') }); $("#my_id").dblclick(function() { $(this).css('backgroundColor', 'green') }); 

这些答案都不满足我的需求,所以我创build了一个灵感来自@AdrienSchuler发布的要点的解决scheme。 只有当你想要绑定一个单击和双击元素时才使用此解决scheme。 否则,我build议使用本地clickdblclick监听器。

这些是不同之处:

  • Vanillajs,没有依赖
  • 不要等待setTimeout来处理单击或双击处理程序
  • 双击它首先触发点击处理程序,然后双击处理程序

使用Javascript:

 function makeDoubleClick(doubleClickCallback, singleClickCallback) { var clicks = 0, timeout; return function() { clicks++; if (clicks == 1) { singleClickCallback && singleClickCallback.apply(this, arguments); timeout = setTimeout(function() { clicks = 0; }, 400); } else { timeout && clearTimeout(timeout); doubleClickCallback && doubleClickCallback.apply(this, arguments); clicks = 0; } }; } 

用法:

 var singleClick = function(){ console.log('single click') }; var doubleClick = function(){ console.log('double click') }; element.addEventListener('click', makeDoubleClick(doubleClick, singleClick)); 

下面是jsfiddle中的用法,jQuerybutton是接受的答案的行为。

的jsfiddle

另一个简单的基于A1rPun答案的香草解决scheme(请参阅他的jQuery解决scheme的小提琴 ,都在这一个 )。

看起来,当用户双击时不触发单击处理程序,单击处理程序必然在延迟后触发。

 var single = function(e){console.log('single')}, double = function(e){console.log('double')}; var makeDoubleClick = function(e) { var clicks = 0, timeout; return function (e) { clicks++; if (clicks == 1) { timeout = setTimeout(function () { single(e); clicks = 0; }, 250); } else { clearTimeout(timeout); double(e); clicks = 0; } }; } document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false); 

这里有一个jeum的任意数量的事件代码的替代:

  var multiClickHandler = function (handlers, delay) { var clicks = 0, timeout, delay = delay || 250; return function (e) { clicks++; clearTimeout(timeout); timeout = setTimeout(function () { if(handlers[clicks]) handlers[clicks](e); clicks = 0; }, delay); }; } cy.on('click', 'node', multiClickHandler({ 1: function(e){console.log('single clicked ', e.cyTarget.id())}, 2: function(e){console.log('double clicked ', e.cyTarget.id())}, 3: function(e){console.log('triple clicked ', e.cyTarget.id())}, 4: function(e){console.log('quadro clicked ', e.cyTarget.id())}, // ... }, 300)); 

这需要一个cytoscape.js应用程序。

使用优秀的jQuery Sparkle插件。 该插件为您提供检测第一次和最后一次点击的选项。 您可以通过检测是否有其他点击是在第一次点击之后使用它来区分click和dblclick。

查看http://balupton.com/sandbox/jquery-sparkle/demo/

我写了一个简单的jQuery插件,让您使用自定义的“singleclick”事件来区分单击和双击:

https://github.com/omriyariv/jquery-singleclick

 $('#someDiv').on('singleclick', function(e) { // The event will be fired with a small delay. console.log('This is certainly a single-click'); } 

我喜欢避免jquery(和其他90-140k库),并且正如所述的浏览器首先处理onclick,所以这里是我在我创build的网站上做的(这个例子还包括获得一个本地xy点击的位置)

 clicksNow-0; //global js, owell function notify2(e, right) { // called from onclick= and oncontextmenu= (rc) var x,y,xx,yy; var ele = document.getElementById('wrap'); // offset fixed parent for local win xy var xxx= ele.offsetLeft; var yyy= ele.offsetTop; //NScape if (document.layers || document.getElementById&&!document.all) { xx= e.pageX; yy= e.pageY; } else { xx= e.clientX; yy= e.clientY; } x=xx-xxx; y=yy-yyy; clicksNow++; // 200 (2/10ths a sec) is about a low as i seem to be able to go setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200); } function processClick(right, x, y) { if (clicksNow==0) return; // already processed as dblclick if (clicksNow==2) alert('dbl'); clicksNow=0; ... handle, etc ... } 

希望有所帮助