我的页面上有一个元素需要附加onclick和ondblclick事件处理程序。单击发生时,它应该执行与双击不同的操作。当我第一次开始尝试这项工作时,我的头开始旋转。显然,双击时onclick总会触发。所以我尝试使用像这样的基于超时的结构......
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
el.onclick = function() {
timer = setTimeout(function() { alert('Single'); }, 150);
}
el.ondblclick = function() {
clearTimeout(timer);
alert('Double');
}
}
但是我得到了不一致的结果(使用IE8)。它可以正常工作很多次,但有时我会两次得到“单一”警报。
以前有人这样做过吗?有没有更有效的方法?
答案 0 :(得分:24)
和Matt一样,当我稍微增加超时值时,我的体验要好得多。此外,为了缓解单击触发两次的问题(无论如何我无法使用更高的计时器重现),我在单击处理程序中添加了一行:
el.onclick = function() {
if (timer) clearTimeout(timer);
timer = setTimeout(function() { alert('Single'); }, 250);
}
这样,如果点击已经设置为触发,它将自行清除以避免重复的“单个”警报。
答案 1 :(得分:10)
如果您收到2个警报,则检测到双击的阈值似乎太小。尝试增加150至300毫秒。
另外 - 我不确定您是否可以保证点击和dblclick被触发的顺序。因此,当你的dblclick被触发时,它会清除第一个点击事件,但是如果它在第二个'click'事件之前触发,那么第二个事件仍将自行触发,你将结束同时启用双击事件和单击事件触发。
我看到了这个潜在问题的两种可能的解决方案:
1)设置实际触发双击事件的另一个超时。在代码中标记双击事件即将触发。然后,当第二个“单击”事件触发时,它可以检查此状态,并说“oops,dbl click pending,所以我什么也不做”
2)第二个选项是根据点击事件交换目标功能。它可能看起来像这样:
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
var firing = false;
var singleClick = function(){
alert('Single');
};
var doubleClick = function(){
alert('Double');
};
var firingFunc = singleClick;
el.onclick = function() {
// Detect the 2nd single click event, so we can stop it
if(firing)
return;
firing = true;
timer = setTimeout(function() {
firingFunc();
// Always revert back to singleClick firing function
firingFunc = singleClick;
firing = false;
}, 150);
}
el.ondblclick = function() {
firingFunc = doubleClick;
// Now, when the original timeout of your single click finishes,
// firingFunc will be pointing to your doubleClick handler
}
}
基本上这里发生的是你让你设置的原始超时继续。它总是会调用firingFunc();唯一改变的是globFunc()实际指向的内容。检测到双击后,将其设置为doubleClick。然后,一旦超时到期,我们总会恢复为单击。
我们还有一个“触发”变量,因此我们知道拦截第二次单击事件。
另一种选择是完全忽略dblclick事件,只需单击一次和计时器就可以检测到它:
window.onload = function() {
var timer;
var el = document.getElementById('testButton');
var firing = false;
var singleClick = function(){
alert('Single');
};
var doubleClick = function(){
alert('Double');
};
var firingFunc = singleClick;
el.onclick = function() {
// Detect the 2nd single click event, so we can set it to doubleClick
if(firing){
firingFunc = doubleClick;
return;
}
firing = true;
timer = setTimeout(function() {
firingFunc();
// Always revert back to singleClick firing function
firingFunc = singleClick;
firing = false;
}, 150);
}
}
这是未经测试的:)
答案 2 :(得分:5)
简单:
obj.onclick=function(e){
if(obj.timerID){
clearTimeout(obj.timerID);
obj.timerID=null;
console.log("double")
}
else{
obj.timerID=setTimeout(function(){
obj.timerID=null;
console.log("single")
},250)}
}//onclick
答案 3 :(得分:0)
小修理
if(typeof dbtimer != "undefined"){
dbclearTimeout(timer);
timer = undefined;
//double click
}else{
dbtimer = setTimeout(function() {
dbtimer = undefined;
//single click
}, 250);
}
答案 4 :(得分:0)
, cellclick :
function(){
setTimeout(function(){
if (this.dblclickchk) return;
setTimeout(function(){
click event......
},100);
},500);
}
, celldblclick :
function(){
setTimeout(function(){
this.dblclickchk = true;
setTimeout(function(){
dblclick event.....
},100);
setTimeout(function(){
this.dblclickchk = false;
},3000);
},1);
}
答案 5 :(得分:0)
我偶然发现这可行(Bing Maps就是这种情况):
pushpin.clickTimer = -1; Microsoft.Maps.Events.addHandler(pushpin, 'click', (pushpin) { return function () { if (pushpin.clickTimer == -1) { pushpin.clickTimer = setTimeout((function (pushpin) { return function () { alert('Single Clic!'); pushpin.clickTimer = -1; // single click handle code here } }(pushpin)), 300); } } }(pushpin))); Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', (function (pushpin) { return function () { alert('Double Click!'); clearTimeout(pushpin.clickTimer); pushpin.clickTimer = -1; // double click handle here } }(pushpin)));
看起来click事件掩盖了dblclick事件,当我们添加超时时,这种用法正在清除它。因此,希望在稍作修改后,这也适用于非Bing Maps的情况,但我没有尝试过。