如何在Konva图形触发contextmenu事件后屏蔽click事件?
嘿,我之前也踩过这个坑!浏览器在右键点击元素时,确实会先触发contextmenu事件,紧接着又自动触发click事件——这是浏览器的默认行为,单纯在contextmenu里阻止默认或冒泡根本拦不住后续的click,因为它们是两个独立触发的事件实例。
给你一个简单靠谱的解决方案:用一个状态标志位来跟踪右键事件的触发状态,从而在click事件里判断是否要跳过执行逻辑。具体思路如下:
- 定义一个变量标记是否刚触发过右键菜单事件
- 在
contextmenu回调里把标志位设为true,同时保留阻止浏览器默认右键菜单的代码 - 在
click回调里先检查标志位:如果是true就直接跳过执行,同时重置标志;如果是false就正常执行左键点击逻辑 - 用
setTimeout延迟重置标志位,避免影响下一次的正常左键点击
下面是修改好的完整代码:
<!DOCTYPE html> <html> <head> <style> body { margin: 0; padding: 0; background-color: #F0F0F0; } .canvas { float: left; width: 50%; } .static-canvas .konvajs-content { background: orange; } </style> </head> <body> <div class="canvas static-canvas"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/9.0.0/konva.min.js"></script> <script> const width = 400; const height = 300; const stage = new Konva.Stage({ container: '.static-canvas', width: width, height: height }); const layer = new Konva.Layer(); const pentagon = new Konva.RegularPolygon({ x: stage.getWidth() / 2, y: stage.getHeight() / 2, sides: 5, radius: 70, fill: 'red', stroke: 'black', strokeWidth: 4 }); layer.add(pentagon); stage.add(layer); // 定义状态标志位,跟踪右键事件是否触发 let isContextMenuTriggered = false; pentagon.on('click', (e) => { // 如果刚触发过右键,直接跳过click逻辑 if (isContextMenuTriggered) { // 延迟重置标志位,确保不影响下一次左键点击 setTimeout(() => { isContextMenuTriggered = false; }, 0); return; } console.log('click'); }); pentagon.on('contextmenu', (e) => { // 阻止浏览器默认右键菜单弹出 e.evt.preventDefault(); // 标记已触发右键事件 isContextMenuTriggered = true; console.log('contextclick'); }); </script> </body> </html>
关键改动说明:
- 新增
isContextMenuTriggered变量做状态跟踪,替代你原来无效的事件阻止代码 - 在
contextmenu回调里只保留e.evt.preventDefault()(用来阻止浏览器默认的右键菜单弹出),同时设置标志位 click回调里先判断标志位,为true时直接返回,不执行后续逻辑;用0延迟的setTimeout把标志位重置操作放到当前事件循环之后,避免干扰下一次的左键点击判断
这样修改后,右键点击只会输出contextclick,不会再触发click事件;左键点击依然正常输出click,完全符合你的需求!
内容来源于stack exchange
相关产品推荐
相关产品推荐

