我有一个带有id为"my_id"
的li元素中只有一个按钮。我给这个元素附加了两个jQuery事件。
1.
$("#my_id").click(function() {
alert('single click');
});
2.
$("#my_id").dblclick(function() {
alert('double click');
});
但每次它都给我
单击
。我有一个带有id为"my_id"
的li元素中只有一个按钮。我给这个元素附加了两个jQuery事件。
1.
$("#my_id").click(function() {
alert('single click');
});
2.
$("#my_id").dblclick(function() {
alert('double click');
});
单击
。原来我们使用更多的临时状态和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
if(evt.detail !== 1) return;
这样的操作拒绝意外的双击将阻止没有鼠标的用户访问该按钮。 - gristowevt.detail
还会追踪双击之外的其他点击,如三连击。 - CubicleSoftdblclick
事件的行为在Quirksmode中有解释。
dblclick
的事件顺序如下:
唯一的例外是(当然)Internet Explorer,它们使用自定义顺序:
如你所见,同时在相同元素上监听这两个事件将导致额外调用click
处理程序。
dblclick
是否可靠... 如果我单击一次... 等待一两秒钟,然后再次单击,第二次单击会触发 dblclick
事件! - Michael在第一次点击后,您需要使用超时来检查是否有另一个点击事件。
// 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://www.quirksmode.org/dom/events/click.html
或者使用jQuery提供的事件:http://api.jquery.com/dblclick/
dblclick
事件。 - Jon z 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>
一个简单的函数。不需要使用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>
el.dataset.dblclick
是更好的方法。 - WORMSS恐怕这种行为取决于浏览器:
不建议为同一元素绑定单击和双击事件处理程序。 触发的事件顺序因浏览器而异,有些浏览器在双击之前接收两个单击事件,而其他浏览器只接收一个单击事件。 双击灵敏度(被检测为双击的点击之间的最大时间)可能因操作系统和浏览器而异,通常可由用户进行配置。
http://api.jquery.com/dblclick/
在Firefox中运行您的代码,click()
处理程序中的alert()会防止您再次点击。 如果删除此警告,则可以同时获得两个事件。
要双击(即点击两次),您必须先单击一次。 click()
处理程序在第一次单击时触发,由于警报弹出,您没有机会进行第二次单击以触发 dblclick()
处理程序。
将处理程序更改为执行与 alert()
不同的其他操作,您将看到不同的行为。 (例如更改元素的背景颜色):
$("#my_id").click(function() {
$(this).css('backgroundColor', 'red')
});
$("#my_id").dblclick(function() {
$(this).css('backgroundColor', 'green')
});
此答案随时间的推移而过时,请查看@kyw的解决方案。
我创建了一个灵感来自@AdrienSchuler发布的要点的解决方案。仅当您想将单击和双击绑定到元素时才使用此解决方案。否则,我建议使用本机click
和dblclick
侦听器。
这些是不同之处:
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));
这是另一个基于A1rPun答案的简单的Vanilla解决方案(请参见他的fiddle获取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);
如何区分单击和双击同一元素?
如果您不需要混合使用它们,可以依靠click
和dblclick
,每个都可以很好地完成工作。
当尝试混合使用它们时会出现问题:dblclick
事件实际上也会触发click
事件,因此您需要确定单击是“独立”的单击还是双击的一部分。
此外:不应在同一元素上同时使用click
和dblclick
:
不建议为同一元素绑定单击和双击事件处理程序。触发的事件序列因浏览器而异,有些浏览器在双击之前接收到两个单击事件,而其他浏览器只有一个单击事件。双击灵敏度(检测为双击的点击之间的最大时间)可能因操作系统和浏览器而异,并且通常可以由用户进行配置。
来源:https://api.jquery.com/dblclick/
现在好消息来了:
您可以使用事件的detail
属性来检测与事件相关的点击次数。这使得在click
内部检测双击相当容易。
问题仍然存在于检测单击以及它们是否是双击的一部分。为此,我们需要使用定时器和setTimeout
。
将所有内容绑定在一起,使用数据属性(避免全局变量)而无需自己计算点击次数:
<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>
<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>
花了一些时间才找到令人满意的解决方案,希望这能有所帮助!
event.detail
区分单击和双击,3. 使用定时器的现代解决方案。 - Gangula