Reputation: 53407
For my webapp I'm working on a popup element, which is used for menus and similar things. I want to redirect all mouse input on the current page to this popup element when it's visible, however I can get it to work.
I have a tile element which, on mouse hover, shows an image (and highlights the tile). When the user clicks on that image the popup is shown (as a context menu). This works already. When the user moves the mouse outside the tile the hover state is gone, the highlight and also the image disappear, which is not what should happen. Instead I want the visual state unaffected as long as the menu is visible.
So I tried to capture the mouse using Element.setPointerCapture. However, this requires a pointer id, which I don't have. I tried to use onPointerDown
on the trigger image, but that didn't do anything.
What's the right way to implement this mouse capture, so that no mouse event is scheduled to any other HTML element, but the popup?
This is what I came up with so far:
private handleTriggerClick = (e: React.MouseEvent): void => {
console.log("mouse");
this.props.trigger?.props.onClick?.(e);
if (this.state.open && this.props.closeOnTriggerClick) {
this.close();
} else if (!this.state.open && this.props.openOnTriggerClick) {
this.open();
e.currentTarget.setPointerCapture(this.pointerId);
}
e.stopPropagation();
};
private handleTriggerPointerDown = (e: React.PointerEvent): void => {
console.log("pointer");
this.pointerId = e.pointerId;
};
where trigger
is the image used to show the popup.
I also tried using a mouse move handler on the document, but that didn't work either, probably because of event bubbling where first the deeper elements receive the event before it reaches the document, so it's too late then to prevent default handling or stop propagation.
Upvotes: 0
Views: 343
Reputation: 136986
The Element.setPointerCapture API will only work when the pointer is in its "active button" mode (that is between pointerdown and pointerup or pointercancel).
I guess it's not exactly what you want...
Maybe requestPointerLock would be closer to what you are asking, but it may also be a bit too much (a confirm message would pop-up asking your users if they wish to let your app control their mouse etc.)
So a third way, probably easier, is to append an overlay element with a fixed position that would cover the whole page, you could make it appear also only when your menu is hovered, but without seeing your actual situation, I can only give such a broad advice.
Upvotes: 1