如何跨平台可靠实现区分左右鼠标按键的事件监听
如何跨平台可靠实现区分左右鼠标按键的事件监听
我之前也碰到过和你一模一样的鼠标按键监听问题,一开始用的是click和contextmenu事件分开处理的写法,代码大概是这样:
document.addEventListener('click', function(e) { const targetEl = e.target; console.log('lc', targetEl); clickCell(targetEl); }, false); document.addEventListener('contextmenu', function(e) { e.preventDefault(); const targetEl = e.target; console.log('rc', targetEl); rightClickCell(targetEl); }, false);
这段代码刚开始用着没问题,但后来发现左键点击时有个奇怪的bug:如果点击过程中鼠标不小心从子元素滑到了父元素(哪怕父元素被子元素完全盖住),触发的目标元素会变成父元素,这明显不符合预期。
我当时也不想直接忽略父元素,那样会漏掉一些合法的点击;改成mouseup事件虽然能解决左键的问题,但右键操作会同时触发mouseup和contextmenu,导致逻辑冲突。折腾了一番后,我改成了下面这种写法:
document.addEventListener('contextmenu', e => e.preventDefault()); document.addEventListener('mouseup', function(e) { const targetEl = e.target; if (e.button === 0) { console.log('lc', targetEl); clickCell(targetEl); } else if (e.button === 2) { console.log('rc', targetEl); rightClickCell(targetEl); } }, false);
目前这个方案在我测试过的所有平台上都能稳定工作:左键(或触控板单指点击)触发clickCell,右键(或触控板双指点击)触发rightClickCell。
关于你担心的跨平台兼容性问题,其实完全不用太焦虑:
- 标准的
e.button取值在所有现代浏览器里都是统一的:0代表左键,2代表右键,不管是Windows、Linux还是Mac系统都遵循这个规范。 - Mac系统的外接鼠标右键、触控板双指点击,都会触发
e.button === 2,加上我们提前阻止了contextmenu的默认行为,不会弹出系统自带的右键菜单,完全符合需求。 - 这个方案还解决了之前左键点击时鼠标移动导致目标元素变化的问题,因为
mouseup是在鼠标松开时获取当前所在的元素,而click需要按下和松开都在同一个元素才会触发。
如果非要挑需要注意的点,那就是:如果你的项目需要兼容IE8及以下的古董浏览器,可能需要额外做兼容性处理,但现在这类浏览器的使用率几乎可以忽略不计,所以不用太纠结。
备注:内容来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

