为什么中间点击在几种情况下不会触发“点击”?
这是我所看到的行为的JSFiddle ,与Chrome和FF中的中间点击和click
事件有关。
‘click’有点实际
方法1 :将click
处理程序直接绑定到元素,然后单击鼠标中键将触发Chrome中的处理程序,但不会触发FF。
$('div a').on('click', function(ev) { // middle click triggers this handler });
方法2 :将委派的click
处理程序绑定到包含一个或多个a
的div
。 中键单击不会在Chrome或FF中触发此处理程序。
$('div').on('click', 'a', function(ev) { // middle click doesn't trigger this handler });
如果div开始为空并且a
元素稍后通过AJAX调用填充,或者作为某些用户输入的结果,则此方法非常有价值。
‘mouseup’有效
使用mouseup
而不是click
会导致方法1和2在两个浏览器中都有效。
// Approach 1 w/ mouseup $('div a').on('mouseup', function(ev) { // middle click **does** trigger this handler in Chrome and FF }); // Approach 2 w/ mouseup $('div').on('mouseup', 'a', function(ev) { // middle click **does** trigger this handler in Chrome and FF });
这是带有mouseup
的JSFiddle 。
这很有趣,在某些情况下可能很有用,因为click
几乎是click
。 但是mouseup
没有 click
,我就是click
后的行为。 我不想创造一个hacky mousedown; setTimeout; mouseup
mousedown; setTimeout; mouseup
click
模拟。
我很确定答案是“nope”,但有一种跨浏览器的方式导致中键点击触发click
处理程序吗? 如果没有,原因是什么?
通常会针对鼠标左键触发click事件,但是,根据浏览器,右侧和/或中间按钮可能会也可能不会发生单击事件。
在Internet Explorer和Firefox中,不会为右侧或中间按钮触发click事件。
因此,我们无法在中间或右侧按钮上可靠地使用事件处理程序的click事件。
相反,要区分鼠标按钮,我们必须使用mousedown和mouseup事件,因为大多数浏览器会为任何鼠标按钮触发mousedown和mouseup事件。
在Firefox和Chrome event.which
应该包含一个数字,表示按下了什么鼠标按钮(1是左,2是中间,3是右)。
另一方面,在Internet Explorer中, event.button
指示单击了什么鼠标按钮(1为左,4为中,2为右);
event.button
也应该在Firefox和其他浏览器中工作,但数字可能略有不同(0为左,1为中,2为右)。
所以把它放在一起我们通常做这样的事情:
document.onmousedown = function(e) { var evt = e==null ? event : e; if (evt.which) { // if e.which, use 2 for middle button if (evt.which === 2) { // middle button clicked } } else if (evt.button) { // and if e.button, use 4 if (evt.button === 4) { // middle button clicked } } }
当jQuery规范化event.which
,你应该只需要在jQuery事件处理程序中使用它,因此这样做:
$('div a').on('mousedown', function(e) { if (e.which === 2) { // middle button clicked } });
换句话说,你不能使用onclick事件,所以要模拟它,你可以使用mousedown和mouseup。
您可以添加一个计时器来限制mousedown和mouseup事件之间允许的时间,甚至可以使用mousemove处理程序来限制mousedown和mouseup事件之间的移动,并且如果鼠标指针移动了十次以上,则不会触发事件处理程序像素等可能性几乎是无穷无尽的,所以这不应该是一个问题。
$('#test').on({ mousedown: function(e) { if (e.which === 2) { $(this).data('down', true); } }, mouseup: function(e) { if (e.which === 2 && $(this).data('down')) { alert('middle button clicked'); $(this).data('down', false); } } });
简短回答:不。
问题是,您希望捕获中间点击的内容是什么? 中间点击不是要与当前页面交互,而是在新选项卡中打开链接。
Chrome目前正在努力放弃此行为: https : //code.google.com/p/chromium/issues/detail? id = 255
目前有关于该主题的w3c邮件列表的一般性讨论: http : //lists.w3.org/Archives/Public/www-dom/2013JulSep/0203.html
但就目前而言,您可以在文档级别上捕获Firefox中的middleclicks:
$(document).on('click', function(e){ console.log(e); });
我已经建立了一个工厂,用于使用vanilla JS创建中鼠标点击处理程序,并在最新的Firefox和Chrome中工作 :
const MiddleClickHandlerFactory = (node, handlerFn) => { node.addEventListener('mousedown', e => { if (e.button !== 1) return; e.preventDefault(); // stop default scrolling crap! Instead install ScrollAnywhere! const originalTarget = e.target; document.addEventListener('mouseup', e => { // register on DOCUMENT to be sure it will fire even if we release it somewhere else if (e.target.isSameNode(originalTarget)) handlerFn(e); }, {capture: true, once: true, passive: true}); }, true) };