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

IT技术 javascript jquery jquery-events
2021-01-29 12:30:53

我在 li 中有一个带有 id 的按钮"my_id"我用这个元素附加了两个 jQuery 事件

1.

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

2.

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

但每次它都给了我 single click

6个回答

dblclick事件的行为Quirksmode 中进行了解释

a 的事件顺序dblclick是:

  1. 鼠标按下
  2. 鼠标向上
  3. 点击
  4. 鼠标按下
  5. 鼠标向上
  6. 点击
  7. 双击

此规则的一个例外是(当然)Internet Explorer,其自定义顺序为:

  1. 鼠标按下
  2. 鼠标向上
  3. 点击
  4. 鼠标向上
  5. 双击

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

event.detail可用时,它是从单击处理程序检测双击的最佳方法。看到这个答案
2021-03-21 12:30:53
这种长时间的点击对于重命名文件很有用。如果有像'longClick'这样的参数来区分它会很好。
2021-03-24 12:30:53
被否决,但不是因为答案错误或不好,而是因为它已经过时,IE 基本不再使用,市场份额为 1%。
2021-03-30 12:30:53
不确定dblclick甚至可靠......如果我点击一次......等待一两秒钟,然后再次点击,我会dblclick在第二次点击时收到一个事件!
2021-04-08 12:30:53

您需要使用超时来检查第一次点击后是否还有一次点击。

这是诀窍

// 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/

很好的解决方案 Adrien,我需要它来处理我们在一个对象上有一个单击和双击事件并且应该只触发一个事件的情况。因此,您的解决方案对我来说是完美的。我只是对其进行了一些改进以控制“这个”:playcode.io/492022
2021-03-13 12:30:53
是的,我认为你是对的,dblclick这绝对是今天要走的路。jQuery 也处理这个事件:api.jquery.com/dblclick
2021-03-18 12:30:53
@AdrienSchuler - 从您链接的文档中:将处理程序绑定到同一元素的 click 和 dblclick 事件是不可取的。问题是关于两者都有
2021-03-28 12:30:53
这在一般情况下似乎工作得很好,但是点击之间允许的延迟时间(两次点击被解释为双击)是否因系统配置而异?依赖dblclick事件可能更安全
2021-03-29 12:30:53
event.detail可用时,它是从单击处理程序检测双击的最佳方法。看到这个答案
2021-04-02 12:30:53

事实证明,没有使用更多的临时状态和 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

好点@FabienSnauwaert。我想我们不能在特定元素上同时绑定单击和双击事件处理程序;上面的方法对于明确确定双击很有用,而无需求助于诸如计时器之类的东西。
2021-03-18 12:30:53
最佳答案:)
2021-03-28 12:30:53
您仍然需要在第一次点击时使用计时器才能不触发。检查我在stackoverflow.com/questions/5497073/...
2021-03-29 12:30:53
只是一个可访问性说明:如果点击事件是由键盘触发的(例如,当用户使用 Tab 键聚焦按钮并按下 Enter 键时),则生成的事件的 detail 属性为 0,因此执行类似if(evt.detail !== 1) return;拒绝意外双倍的操作单击将阻止没有鼠标的用户访问该按钮。
2021-04-02 12:30:53
在双击的情况下,单击(其中event.detail === 1)仍会触发。请参阅我的小提琴此线程上的此评论
2021-04-06 12:30:53

一个简单的功能。不需要 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>
我认为这应该是最好的答案。但是,我必须将超时减少到 200 才能在 Windows IE8 上运行,但该值可能取决于操作系统和用户。并且还保存了计时​​器引用,以便在注册双击时能够取消单击的执行。
2021-03-29 12:30:53
event.detail可用时,它是从单击处理程序检测双击的最佳方法。看到这个答案
2021-03-31 12:30:53
感谢您提供这段代码,它在 chrome 和 firefox 上运行良好(尽管 chrome 不需要这个 hack 来处理 dbl 和 single)。
2021-04-08 12:30:53
现在使用el.dataset.dblclick将是一个更好的方法。
2021-04-08 12:30:53

现代正确答案是接受的答案和@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>

解决了我的问题。唯一的问题是它稍微影响了我的表现,但可以忽略不计。
2021-03-21 12:30:53