如何区分单击事件和双击事件?
我在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
的事件顺序是:
- 鼠标按下
- 鼠标松开
- 点击
- 鼠标按下
- 鼠标松开
- 点击
- DBLCLICK
这个规则的一个例外是(当然)Internet Explorer与他们的自定义顺序:
- 鼠标按下
- 鼠标松开
- 点击
- 鼠标松开
- 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议使用本地click
和dblclick
监听器。
这些是不同之处:
- 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。
我写了一个简单的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 ... }
希望有所帮助