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

我用 id "my_id"创建了一个单独的按钮 li,并用这个元素附加了两个 jQuery 事件

1.

$("#my_id").click(function() {
alert('single click');
});

2.

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

但每次它都给我 single click

200945 次浏览

为了双击(点击两次) ,你必须先点击一次。click()处理程序在您第一次单击时触发,并且由于警报弹出,您没有机会进行第二次单击以触发 dblclick()处理程序。

更改您的处理程序以执行 alert()以外的操作,您将看到这种行为。(可能改变元素的背景颜色) :

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


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

我担心这种行为是由浏览器决定的:

不建议将处理程序绑定到 的 click 和 dblclick 事件 同一个元素 触发的事件因浏览器而异 浏览器,其中一些收到两个 在 dblclick 和 其他只有一个。双击 灵敏度(最大间隔时间 检测为 double 的单击 点击)可以根据操作系统的不同而变化 和浏览器,并经常 用户可配置。

Http://api.jquery.com/dblclick/

在 Firefox 中运行代码时,click()处理程序中的 alert ()会阻止您第二次单击。如果删除此类警报,则会同时获得这两个事件。

使用杰出的 jQuery Sparkle 插件。这个插件提供了检测第一次和最后一次点击的选项。您可以使用它来区分 click 和 dblclick,方法是检测是否在另一次 click 之后紧跟着第一次 click。

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

dblclick事件的行为在 古克斯莫德中解释。

dblclick的事件顺序是:

  1. 鼠标向下
  2. 小老鼠
  3. 点击
  4. 鼠标向下
  5. 小老鼠
  6. 点击
  7. Dblclick

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

  1. 鼠标向下
  2. 小老鼠
  3. 点击
  4. 小老鼠
  5. Dblclick

如您所见,在同一个元素上同时侦听两个事件将导致对 click处理程序的额外调用。

我喜欢避免使用 jquery (和其他90-140k 库) ,并且作为著名的浏览器处理 onclick 的第一步,所以这里是我在我创建的网站上所做的(这个例子也包括获得一个单击的本地 x y 位置)

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 x y
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 ...
}

希望能帮上忙

一个简单的函数。不需要 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>

这个答案随着时间的推移已经过时了,请查看@kyw 的解决方案。

我创造了一个解决方案,灵感来自@AdrienSchuler 发布的要点。仅当要将单击和双击绑定到元素时才使用此解决方案。否则,我建议使用本机 clickdblclick侦听器。

这些不同之处在于:

  • 香草,没有依赖
  • 不要等待 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 中的用法,jQuery 按钮是接受答案的行为。

Jsfiddle

我编写了一个简单的 jQuery 插件,它可以让你使用一个自定义的“ singlecclick”事件来区分单击和双击:

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');
}

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

似乎不触发一个单击处理程序时,用户双击,单击处理程序必须在一个延迟后触发..。

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应用程序需要这个。

与使用更多的 ad-hoc 状态和 setTimeout 相反,有一个称为 detail的本机属性可以从 event对象访问!

element.onclick = event => {
if (event.detail === 1) {
// it was a single click
} else if (event.detail === 2) {
// it was a double click
}
};

现代浏览器,甚至 IE-9都支持它:)

资料来源: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

如何区分同一个元素的单击和双击?

如果你不需要混合他们,你可以依赖于 clickdblclick,每个都会做的工作很好。

当试图混合它们时会出现一个问题: ABC0事件实际上也会触发 click事件,因此您需要确定单击是“独立”单击,还是双击的一部分。

此外: 不应该在同一个元素上同时使用 ABC0和 dblclick:

不建议将处理程序绑定到同一元素的 click 和 dblclick 事件。触发的事件顺序因浏览器而异,有些在 dblclick 之前接收到两个 click 事件,有些只接收到一个。双击敏感性(双击检测到的最大单击间隔时间)可以因操作系统和浏览器而异,并且通常是用户可配置的。
资料来源: http://api.jquery.com/dblclick/rel = “ norefrer”> https://api.jquery.com/dblclick/

好消息是:

您可以使用事件的 detail属性来检测与该事件相关的单击次数 。这使得 click内部的双击相当容易被检测到。

问题仍然是检测单次点击以及它们是否是双击的一部分。为此,我们回到使用定时器和 setTimeout

通过使用 data 属性(以避免全局变量)将它们包装在一起,不需要自己计算点击次数,我们得到:

HTML:

<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>


<div id="log" style="background: #efefef;"></div>

JavaScript:

<script>
var clickTimeoutID;
$( document ).ready(function() {


$( '.clickit' ).click( function( event ) {


if ( event.originalEvent.detail === 1 ) {
$( '#log' ).append( '(Event:) Single click event received.<br>' );


/** Is this a true single click or it it a single click that's part of a double click?
* The only way to find out is to wait it for either a specific amount of time or the `dblclick` event.
**/
clickTimeoutID = window.setTimeout(
function() {
$( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
},
500 // how much time users have to perform the second click in a double click -- see accessibility note below.
);


} else if ( event.originalEvent.detail === 2 ) {
$( '#log' ).append( '(Event:) Double click event received.<br>' );
$( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
window.clearTimeout( clickTimeoutID ); // it's a dblclick, so cancel the single click behavior.
} // triple, quadruple, etc. clicks are ignored.


});


});
</script>

演示:

JSfiddle


关于可访问性和双击速度的注释:

  • 正如维基百科所说: “连续两次点击被解释为双击所需的最大延迟是不标准化的。”
  • 无法检测系统在浏览器中的双击速度。
  • 似乎默认值是500ms,在 Windows 上的范围是100-900ms (来源)
  • 想想那些在操作系统设置中将双击速度设置为最慢的残疾人。
    • 如果系统双击速度低于默认的500毫秒以上,单击和双击行为都将被触发。
    • 不要使用单击和双击相结合的同一个项目。
    • 或者: 在选项中添加一个设置,以便能够增加值。

找到一个令人满意的解决方案花了一段时间,我希望这有所帮助!

这对我很管用

var clicked=0;
function chkBtnClcked(evnt) {
clicked++;
// wait to see if dblclick
if (clicked===1) {
setTimeout(function() {
clicked=0;
.
.
}, 300); // test for another click within 300ms
}
if (clicked===2) {
stopTimer=setInterval(function() {
clicked=0;
.
.
}, 30*1000); // refresh every 30 seconds
}
}

用途-

<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)"  title="Click for next pic; double-click for slide show"></div>

只是张贴原生的 HTML 答案,以防万一的需要是简单和 HTML。

<p ondblclick="myFunction()" id = 'id'>Double-click me</p>

这当然有本机 Jquery 选项。即... $('#id').attr('ondblclick',function(){...})或者,如前所述,$('#id').dblclick(function(){...});

我知道这是老的,但下面是一个 JS 的基本循环计数器与单一计时器,以确定一个单一与双击只有一个例子。希望这能帮到别人。

var count = 0;
var ele = document.getElementById("my_id");
ele.addEventListener('click', handleSingleDoubleClick, false);


function handleSingleDoubleClick()
{
if(!count) setTimeout(TimerFcn, 400); // 400 ms click delay
count += 1;
}
function TimerFcn()
{
if(count > 1) console.log('you double clicked!')
else console.log('you single clicked')
count = 0;
}

现代的正确答案是公认的答案和@kyw 的解决方案的混合。 您需要一个超时来阻止第一次单击,而 event.detail检查来阻止第二次单击。

const button = document.getElementById('button')
let timer
button.addEventListener('click', event => {
if (event.detail === 1) {
timer = setTimeout(() => {
console.log('click')
}, 200)
}
})
button.addEventListener('dblclick', event => {
clearTimeout(timer)
console.log('dblclick')
})
<button id="button">Click me</button>

基于 Adrien Schuler(非常感谢! ! !)的答案,对于 Datatables.net和许多用途,这里有一个修改:

功能

/**
* For handle click and single click in child's objects
* @param {any} selector Parents selector, like 'tr'
* @param {any} single_click_callback Callback for single click
* @param {any} double_click_callback Callback for dblclick
* @param {any} timeout Timeout, optional, 300 by default
*/
jQuery.fn.single_double_click = function (selector, single_click_callback, double_click_callback, timeout) {
return this.each(function () {
let clicks = 0;
jQuery(this).on('click', selector, function (event) {
let self = this;
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);
}
});
});
}

使用

$("#MyTableId").single_double_click('tr',
function () {   //  Click
let row = MyTable.row(this);
let id = row.id();
let data = row.data();
console.log("Click in "+id+" "+data);
},
function () {   //  DBLClick
let row = MyTable.row(this);
let id = row.id();
let data = row.data();
console.log("DBLClick in "+id+" "+data);
}
);
let clickTimes = 0;
let timer = null;
roundBox.click = function (e) {
clearTimeout(timer);
timer = setTimeout(() => { // 单击事件
console.log("single click");
}, 600);
clickTimes++;


if (clickTimes == 2) { // 双击
clearTimeout(timer);
clickTimes = 0;
console.log("double click");
toggleExpanded(id);
}
}

试试这个代码

let click = 0;
element.onclick = (event) => {
click++;
console.log(click);
setTimeout(() => {
click = 0;
}, 300);
if (click === 2) {
console.log("double Click");
click = 0;
console.log(click);
}
};

如果您想区分单击和双击,单击的事件处理程序必须等到证明单击不是双击的开始。这使得单次点击滞后。这个例子说明了这一点。

var distinguish = (() => {
var target = null;
var timeout = null;
return (element, action) => {
element.addEventListener ('click', e => {
if (e.target === target) {
clearTimeout (timeout);
target = null;
timeout = null;
action ('double');
} else {
target = e.target;
timeout = setTimeout (() => {
target = null;
timeout = null;
action ('single');
}, 500);
}
});
};
})();


var button = document.getElementById ('button');


distinguish (button, kind => console.log (kind + ' click'));
<input id="button" type="button" value="click">