当检测到双击事件时,需要取消单击/鼠标松开事件。

49

这该怎么做?


1
对于同一元素还是整个文档? - rahul
5个回答

80

这是一个很好的问题,我认为它并不容易解决。(这里有一些相关讨论)

如果你非常需要这个功能,可以通过以下方式进行修改:

function singleClick(e) {
    // do something, "this" will be the DOM element
}

function doubleClick(e) {
    // do something, "this" will be the DOM element
}

$(selector).click(function(e) {
    var that = this;
    setTimeout(function() {
        var dblclick = parseInt($(that).data('double'), 10);
        if (dblclick > 0) {
            $(that).data('double', dblclick-1);
        } else {
            singleClick.call(that, e);
        }
    }, 300);
}).dblclick(function(e) {
    $(this).data('double', 2);
    doubleClick.call(this, e);
});

这里有一个它的工作示例

评论中提到,有一个插件可以做到我上面所做的事情,但是它将其打包起来,让你不必看到丑陋的代码:FixClick


1
其实,我能不能在双击期间阻止后续的单击事件呢?我认为这可以解决延迟问题。 - Daddy Warbox
5
顺便说一下,似乎已经有一个插件可以解决这个问题了,它叫做http://plugins.jquery.com/project/FixClick,类似于Paolo Bergantino所提出的解决方案。 - jitter
就算不值得一提,这里有另一个插件的源代码,可以实现同样的功能(在其他回答中提到),其使用自定义/特殊事件: http://bit.ly/diBCkI - balupton
2
jQuery插件网站已经崩溃,但是在jQuery网站的评论部分链接到了这个不错的GitHub jQuery扩展https://gist.github.com/399624。 - Martin Belcher - AtWrk
花了一天的时间在IE中解决问题。感谢Martin! - Babu
显示剩余5条评论

35

雷蒙德·陈(Raymond Chen)讨论了单击与双击的一些含义 - 尽管他是在Windows环境下谈论,但他所说的对于基于浏览器的UI设计也是相关的。

基本上,在双击时执行的操作应该是单击后逻辑上要做的事情。例如,在桌面UI中,单击选择一个项目,双击打开它(例如,打开文件或启动应用程序)。用户必须先选择要打开的文件,因此单击操作在双击操作之前执行并不重要。

如果您有一个UI组件,其双击操作与单击操作完全无关,以至于一旦系统意识到实际上是双击操作,就需要防止单击操作发生,那么您真的应该重新考虑您的设计。用户会觉得笨拙和违反直觉,因为它不会像他们习惯的东西那样运作。

如果您仍然想走这条路,那么您将不得不使用去抖动技术(在这种情况下,所有单击操作都将延迟),否则实现一些机制,使双击处理程序撤消单击处理程序完成的工作。

您还应该知道,一些用户设置了非常长的双击时间。例如,患有关节炎的人可能将其系统首选项中的双击时间设置为超过一秒钟,因此基于您选择的任意时间段的去抖动技术将使单击操作排除双击操作的UI组件无法访问这些人。据我所知,“撤销刚才发生的单击操作”技术是唯一可行的解决方法。


关于用户能够设置自己的双击时间这一点很好。我不想在执行单击操作之前等待整整一秒钟,因此等待带超时的双击实际上是没有意义的。 - Hrqls
有时候,双击动作是单击后的逻辑跟进,而且在执行双击动作之前先执行单击动作也可能是可以的(这就是我现在的做法),但是单击动作可能会导致一些额外的负荷(或者,在我的情况下,数据流量),你可能想要避免这种情况(尽管它并不会造成实质性的伤害)。 - Hrqls

8

其他答案中提到的技术被称为去抖动


1
很酷的东西和不错的文章。+1 - Paolo Bergantino

1

jQuery Sparkle 提供了一个干净优雅的解决方案,通过实现单击自定义事件。通过这样做,您可以像使用任何其他事件一样使用它:

$('#el').singleclick(function(){});
// or event
$('#el').bind('singleclick', function(){});

它还为一系列点击的最后一个和第一个点击提供自定义事件。而lastclick自定义事件实际上将点击数量传回!所以你可以这样做!
$('#el').lastclick(function(event,clicks){
    if ( clicks === 3 ) alert('Tripple Click!');
});

您可以在这里找到定义自定义事件的源代码。

它是根据AGPL许可证的开源软件,所以您可以放心地随意获取所需! :-) 它也在日常基础上积极开发,因此您永远不会缺少支持。

但最重要的是,它是一个DRY插件/效果框架,可以让您更轻松地开发插件和扩展。希望这能帮助您实现这个目标!


0
如果这是用于提交表单的按钮(这不一定是原帖作者的情况,但可能是通过谷歌到达此处的其他人的情况),更简单的选择是在单击事件处理程序中禁用被单击的元素:
$(selector).click(function(e) {
    $(this).prop('disable', true);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接