javascript - onPointerOver and onPointerOut detect all child elements - Stack Overflow

时间: 2025-01-06 admin 业界

The problem is that I have onPointerOver and onPointerOut triggered on each child element, but I need it to be on a common group, because then the component is re-rendered too often.

There is a group here, and now when I move the mouse cursor, the component is redrawn many times, I want my state to change only 1 time when I move the mouse cursor and move it away.

This is changing, but the fact is that my head consists of many InstancedMesh, and it turns out that this state changes for each square that my head consists of.

How do I make this work only for the entire group, that is, so that when I hover the cursor, it only reacts to the entire group, and not to individual squares?

Sandbox

    <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();
  };

The problem is that I have onPointerOver and onPointerOut triggered on each child element, but I need it to be on a common group, because then the component is re-rendered too often.

There is a group here, and now when I move the mouse cursor, the component is redrawn many times, I want my state to change only 1 time when I move the mouse cursor and move it away.

This is changing, but the fact is that my head consists of many InstancedMesh, and it turns out that this state changes for each square that my head consists of.

How do I make this work only for the entire group, that is, so that when I hover the cursor, it only reacts to the entire group, and not to individual squares?

Sandbox

    <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();
  };
Share Improve this question edited 6 hours ago Vadim Semashko asked yesterday Vadim SemashkoVadim Semashko 211 silver badge2 bronze badges New contributor Vadim Semashko is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1
  • 2 Any chance for Sandbox, because is quite wide topic? – Łukasz Daniel Mastalerz Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0

Capture phase events may be useful here

A sample code below shows the same. The code uses click event for demo purpose.

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>;
}

Test run

On load of the App

On clicking on the text Child

Console log generated as below:

// Parent captured

Observation:

Though the click event has been handled in the child component, this handler did not fire when clicking on it. This is due to the capture click event in Parent. It captures the click. Additionally parent stops its propagation too. Since the event propagation has been stopped in Parent, it does not propagate to Child.