I'm trying to build a React app where a user touches one element and then moves to a neighboring element while still holding down. The pointerover and pointerenter events fire when the user touches the first element, but not when the user moves the pointer to the neighboring element. I would like to know when the pointer enters any element, regardless of whether the touch started in that element. (If the pointer element is a mouse instead of touch, this point and drag behavior does work as I expect.)
Example code pen trying out various events: If you use a mouse, the pointerover and pointerenter events are fired when you enter an element even if the mouse was clicked and then dragged into the element. (This is my desired behavior.) However, if you use touch, when you touch down and then move the touch into a different element, the pointerover and pointerenter are not fired for that second element.
Code from the codepen
JSX
function App() {
function myF(e, myv) {
// e.preventDefault()
console.log(`POINTER ${myv}`)
}
return (
<div className="App">
<div>
<div onPointerMove={(e) => myF(e, "a")}>pointer move</div>
<div onPointerMove={(e) => myF(e, "b")}>pointer move</div>
<div onPointerOver={(e) => myF(e, "a")}>pointer over</div>
<div onPointerOver={(e) => myF(e, "b")}>pointer over</div>
<div onPointerEnter={(e) => myF(e, "a")}>pointer enter</div>
<div onPointerEnter={(e) => myF(e, "b")}>pointer enter</div>
<div onPointerMoveCapture={(e) => myF(e, "a")}>pointer move capture</div>
<div onPointerMoveCapture={(e) => myF(e, "b")}>pointer move capture</div>
</div>
<div>
<div className="no-touch" onPointerMove={(e) => myF(e, "a")}>pointer move, touch-action none</div>
<div className="no-touch" onPointerMove={(e) => myF(e, "b")}>pointer move, touch-action none</div>
<div className="no-touch" onPointerOver={(e) => myF(e, "a")}>pointer over, touch-action none</div>
<div className="no-touch" onPointerOver={(e) => myF(e, "b")}>pointer over, touch-action none</div>
<div className="no-touch" onPointerEnter={(e) => myF(e, "a")}>pointer enter, touch-action none</div>
<div className="no-touch" onPointerEnter={(e) => myF(e, "b")}>pointer enter, touch-action none</div>
<div className="no-touch" onPointerMoveCapture={(e) => myF(e, "a")}>pointer move capture, touch-action none</div>
<div className="no-touch" onPointerMoveCapture={(e) => myF(e, "b")}>pointer move capture, touch-action none</div>
</div>
<div>
<div onTouchMove={(e) => myF(e, "a")}>touch move</div>
<div onTouchMove={(e) => myF(e, "b")}>touch move</div>
<div onTouchMoveCapture={(e) => myF(e, "a")}>Touch move capture</div>
<div onTouchMoveCapture={(e) => myF(e, "b")}>Touch move capture</div>
</div>
<div>
<div onMouseMove={(e) => myF(e, "a")}>mouse move</div>
<div onMouseMove={(e) => myF(e, "b")}>mouse move</div>
<div onMouseOver={(e) => myF(e, "a")}>mouse over</div>
<div onMouseOver={(e) => myF(e, "b")}>mouse over</div>
<div onMouseEnter={(e) => myF(e, "a")}>mouse enter</div>
<div onMouseEnter={(e) => myF(e, "b")}>mouse enter</div>
<div onMouseMoveCapture={(e) => myF(e, "a")}>mouse move capture</div>
<div onMouseMoveCapture={(e) => myF(e, "b")}>mouse move capture</div>
</div>
</div>
);
}
ReactDOM.render(<App />,
document.getElementById("root"))
CSS
.App {
display: flex;
flex-direction: row;
}
div {
border: 1px solid black;
padding: 10px;
}
.no-touch {
touch-action: none;
/* pointer-events: all; */
}
HTML
<div id="root">
</div>
I'm trying to build a React app where a user touches one element and then moves to a neighboring element while still holding down. The pointerover and pointerenter events fire when the user touches the first element, but not when the user moves the pointer to the neighboring element. I would like to know when the pointer enters any element, regardless of whether the touch started in that element. (If the pointer element is a mouse instead of touch, this point and drag behavior does work as I expect.)
Example code pen trying out various events: https://codepen.io/skedwards88/pen/OJOXwRm If you use a mouse, the pointerover and pointerenter events are fired when you enter an element even if the mouse was clicked and then dragged into the element. (This is my desired behavior.) However, if you use touch, when you touch down and then move the touch into a different element, the pointerover and pointerenter are not fired for that second element.
Code from the codepen
JSX
function App() {
function myF(e, myv) {
// e.preventDefault()
console.log(`POINTER ${myv}`)
}
return (
<div className="App">
<div>
<div onPointerMove={(e) => myF(e, "a")}>pointer move</div>
<div onPointerMove={(e) => myF(e, "b")}>pointer move</div>
<div onPointerOver={(e) => myF(e, "a")}>pointer over</div>
<div onPointerOver={(e) => myF(e, "b")}>pointer over</div>
<div onPointerEnter={(e) => myF(e, "a")}>pointer enter</div>
<div onPointerEnter={(e) => myF(e, "b")}>pointer enter</div>
<div onPointerMoveCapture={(e) => myF(e, "a")}>pointer move capture</div>
<div onPointerMoveCapture={(e) => myF(e, "b")}>pointer move capture</div>
</div>
<div>
<div className="no-touch" onPointerMove={(e) => myF(e, "a")}>pointer move, touch-action none</div>
<div className="no-touch" onPointerMove={(e) => myF(e, "b")}>pointer move, touch-action none</div>
<div className="no-touch" onPointerOver={(e) => myF(e, "a")}>pointer over, touch-action none</div>
<div className="no-touch" onPointerOver={(e) => myF(e, "b")}>pointer over, touch-action none</div>
<div className="no-touch" onPointerEnter={(e) => myF(e, "a")}>pointer enter, touch-action none</div>
<div className="no-touch" onPointerEnter={(e) => myF(e, "b")}>pointer enter, touch-action none</div>
<div className="no-touch" onPointerMoveCapture={(e) => myF(e, "a")}>pointer move capture, touch-action none</div>
<div className="no-touch" onPointerMoveCapture={(e) => myF(e, "b")}>pointer move capture, touch-action none</div>
</div>
<div>
<div onTouchMove={(e) => myF(e, "a")}>touch move</div>
<div onTouchMove={(e) => myF(e, "b")}>touch move</div>
<div onTouchMoveCapture={(e) => myF(e, "a")}>Touch move capture</div>
<div onTouchMoveCapture={(e) => myF(e, "b")}>Touch move capture</div>
</div>
<div>
<div onMouseMove={(e) => myF(e, "a")}>mouse move</div>
<div onMouseMove={(e) => myF(e, "b")}>mouse move</div>
<div onMouseOver={(e) => myF(e, "a")}>mouse over</div>
<div onMouseOver={(e) => myF(e, "b")}>mouse over</div>
<div onMouseEnter={(e) => myF(e, "a")}>mouse enter</div>
<div onMouseEnter={(e) => myF(e, "b")}>mouse enter</div>
<div onMouseMoveCapture={(e) => myF(e, "a")}>mouse move capture</div>
<div onMouseMoveCapture={(e) => myF(e, "b")}>mouse move capture</div>
</div>
</div>
);
}
ReactDOM.render(<App />,
document.getElementById("root"))
CSS
.App {
display: flex;
flex-direction: row;
}
div {
border: 1px solid black;
padding: 10px;
}
.no-touch {
touch-action: none;
/* pointer-events: all; */
}
HTML
<div id="root">
</div>
Share
Improve this question
asked Feb 3, 2022 at 15:19
skedwards88skedwards88
4096 silver badges9 bronze badges
2 Answers
Reset to default 11Solved thanks to this ment: https://github./w3c/pointerevents/issues/178#issuement-1029108322
e.g. adding onPointerDown={(e) => handlePointerDown(e)}
to my element and defining handlePointerDown
as:
function handlePointerDown(e) {
e.target.releasePointerCapture(e.pointerId)
}
I made a newbie mistake of declaring the functional ponent within the top level App ponent. More details here for anyone else having this same problem: https://github./facebook/react/issues/23238#issuement-1031936780