javascript - onPointerOver 和 onPointerOut 检测所有子元素
问题是我在每个子元素上都触发了onPointerOver和onPointerOut,但我需要它在一个公共组上触发,因为那样组件就不会被重新渲染得太频繁。
这里有一个组,现在当我移动鼠标光标时,组件会被重绘很多次,我希望当我移动鼠标光标并移开时,我的状态只改变一次。
这一点正在改变,但事实是我的头由许多InstancedMesh组成,结果我的头所组成的每个方块的状态都会发生变化。
我如何让这只对整个组生效,也就是说,当我将光标悬停时,它只对整个组作出反应,而不是对单个方块作出反应?
沙盒
<group
position={position}
onPointerOver={(e) => {
e.stopPropagation();
handlePointerOver(e);
}}
onPointerOut={(e) => {
e.stopPropagation();
handlePointerOut(e);
}}
>
<Head scale={scale} isVisibleGrid={isVisibleGrid} position={scaledPosition(0, 24, 0)} />
</group>
const handlePointerOver = (e: ThreeEvent<PointerEvent>) => {
setIsVisibleGrid(true);
e.stopPropagation();
};
const handlePointerOut = (e: ThreeEvent<PointerEvent>) => {
setIsVisibleGrid(false);
e.stopPropagation();
};
答案#1
捕获阶段事件在这里可能有用
下面的示例代码展示了相同的内容。该代码使用点击事件仅作演示用途。
App.js
export default function App() {
return (
<>
<div
onClickCapture={(e) => {
console.log('Parent captured');
e.stopPropagation();
}}
>
Parent
<br />
<Child />
</div>
</>
);
}
function Child() {
return <div onClick={(e) => console.log('Child listened')}>Child</div>;
}
测试运行
应用加载时
点击文本 子项
控制台日志生成如下:
// Parent captured
观察:
尽管点击事件已经在子组件中处理过,但在点击它时该处理程序没有触发。这是因为父组件中捕获了点击事件。它捕获了点击事件。此外,父组件还阻止了事件传播。由于事件传播在父组件中被停止,因此它不会传播到子组件。
