如何在元素上同时使用onclick和ondblclick?

Jos*_*ola 25 javascript double-click

我的页面上有一个元素,我需要附加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');
  }
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了不一致的结果(使用IE8).它可以正常工作,但有时我会两次得到"单一"警报.

有没有人这样做过?有更有效的方法吗?

Sol*_*nal 26

和Matt一样,当我略微增加超时值时,我有了更好的体验.此外,为了缓解单击触发两次的问题(无论如何我无法使用更高的计时器重现),我在单击处理程序中添加了一行:

el.onclick = function() {
    if (timer) clearTimeout(timer);
    timer = setTimeout(function() { alert('Single'); }, 250);        
}
Run Code Online (Sandbox Code Playgroud)

这样,如果click已经设置为fire,它将自行清除以避免重复的"Single"警报.

  • 哇,我喜欢你答案的简单.我想你可以将dblclick监听器全部放在一起并将你的IF块替换为:{clearTimeout(timer); myDoubleClickHandler(); 返回; } (4认同)

Mat*_*att 11

如果您收到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        
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上这里发生的是你让你设置的原始超时继续.它总是会调用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);

  }
}
Run Code Online (Sandbox Code Playgroud)

这是未经测试的:)


Ole*_*rpa 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
Run Code Online (Sandbox Code Playgroud)