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

如何在React-Three-Fiber中阻止默认右键上下文菜单?

解决方案

方法1:全局拦截contextmenu事件

直接在渲染画布(比如Three.js的canvas)上监听contextmenu事件,判断点击的是不是目标mesh,再阻止默认菜单弹出:

const canvas = renderer.domElement;
canvas.addEventListener('contextmenu', (event) => {
  // 用射线检测判断是否点击了目标mesh
  const raycaster = new THREE.Raycaster();
  const mouse = new THREE.Vector2();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  const hits = raycaster.intersectObject(yourMesh);
  
  if (hits.length > 0) {
    event.preventDefault(); // 阻止默认菜单
    showCustomMenu(event.clientX, event.clientY); // 触发你的自定义菜单
  }
});

这种方式不依赖mesh的pointerUp事件状态,直接从根源搞定默认菜单。

方法2:修改pointerUp事件的被动属性

如果是用addEventListener绑定的pointerUp事件,绑定的时候显式设置passive: false,这样就能调用preventDefault()了:

yourMesh.addEventListener('pointerup', (event) => {
  if (event.button === 2) {
    event.preventDefault();
    showCustomMenu(event.clientX, event.clientY);
  }
}, { passive: false });

注意:要是用的是框架内置的事件绑定(比如Three.js的一些封装),可能没法直接设置这个选项,这时候方法1更靠谱。

方法3:在pointerDown阶段提前拦截

右键点击会依次触发pointerdown、pointerup、contextmenu,所以可以在pointerdown时就拦截右键的默认行为:

yourMesh.addEventListener('pointerdown', (event) => {
  if (event.button === 2) {
    event.preventDefault();
  }
}, { passive: false });

// 继续在pointerup里处理自定义菜单逻辑
yourMesh.addEventListener('pointerup', (event) => {
  if (event.button === 2) {
    showCustomMenu(event.clientX, event.clientY);
  }
});

内容的提问来源于stack exchange,提问作者TheKalashnikov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:10:04