You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Konva图形触发contextmenu事件后屏蔽click事件?

如何在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>

关键改动说明:

  1. 新增isContextMenuTriggered变量做状态跟踪,替代你原来无效的事件阻止代码
  2. 在contextmenu回调里只保留e.evt.preventDefault()(用来阻止浏览器默认的右键菜单弹出),同时设置标志位
  3. click回调里先判断标志位,为true时直接返回,不执行后续逻辑;用0延迟的setTimeout把标志位重置操作放到当前事件循环之后,避免干扰下一次的左键点击判断

这样修改后,右键点击只会输出contextclick,不会再触发click事件;左键点击依然正常输出click,完全符合你的需求!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 03:10:07