Material-UI上下文菜单不会阻止新的上下文菜单事件?

时间:2019-11-08 15:48:23

标签: material-ui

Material-UI文档提供了example of how to build a context menu。但是当打开此菜单时,页面的所有元素似乎都停止接收onContextMenu事件。因此,如果您在菜单打开时在菜单外单击鼠标右键,则该应用程序将无法识别所单击的内容,并且将无法重新定位菜单。唯一的选择是首先关闭菜单(例如,通过在菜单外部单击鼠标左键),然后右键单击所需的元素。

如何创建菜单,以便在打开菜单时仍能识别页面的哪些元素被右键单击,并将菜单重新放置到新点击的位置?

(请参阅此Codesandox,它是对文档示例的略微修改,其中添加了第二个div,您可以右键单击)

1 个答案:

答案 0 :(得分:0)

找到了解决方案!技巧是在父div的鼠标按下事件上关闭上下文菜单,并在菜单上将退出transitionDuration设置为0。例如,请参见此demo.tsx(也在Codesandox上):

import React from "react";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import Typography from "@material-ui/core/Typography";

const initialState = {
  mouseX: null,
  mouseY: null
};

export default function ContextMenu() {
  const [state, setState] = React.useState<{
    mouseX: null | number;
    mouseY: null | number;
  }>(initialState);

  const handleClick = (
    divName: string,
    event: React.MouseEvent<HTMLDivElement>
  ) => {
    console.log(divName);
    event.preventDefault();
    setState({
      mouseX: event.clientX - 2,
      mouseY: event.clientY - 4
    });
  };

  const handleClose = () => {
    setState(initialState);
  };

  return (
    <div
      onContextMenu={e => e.preventDefault()}
      onMouseDownCapture={e => {
        if (e.button === 2) handleClose();
      }}
    >
      <Menu
        keepMounted
        open={state.mouseY !== null}
        onClose={handleClose}
        anchorReference="anchorPosition"
        anchorPosition={
          state.mouseY !== null && state.mouseX !== null
            ? { top: state.mouseY, left: state.mouseX }
            : undefined
        }
        transitionDuration={0}
      >
        <MenuItem onClick={handleClose}>Copy</MenuItem>
        <MenuItem onClick={handleClose}>Print</MenuItem>
        <MenuItem onClick={handleClose}>Highlight</MenuItem>
        <MenuItem onClick={handleClose}>Email</MenuItem>
      </Menu>
      <div
        onContextMenu={e => handleClick("div1", e)}
        style={{ cursor: "context-menu" }}
      >
        <Typography>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum
          purus, bibendum sit amet vulputate eget, porta semper ligula. Donec
          bibendum vulputate erat, ac fringilla mi finibus nec. Donec ac dolor
          sed dolor porttitor blandit vel vel purus. Fusce vel malesuada ligula.
          Nam quis vehicula ante, eu finibus est. Proin ullamcorper fermentum
          orci, quis finibus massa. Nunc lobortis, massa ut rutrum ultrices,
          metus metus finibus ex, sit amet facilisis neque enim sed neque.
          Quisque accumsan metus vel maximus consequat. Suspendisse lacinia
          tellus a libero volutpat maximus.
        </Typography>
      </div>
      -----
      <div
        onContextMenu={e => handleClick("div2", e)}
        style={{ cursor: "context-menu" }}
      >
        <Typography>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum
          purus, bibendum sit amet vulputate eget, porta semper ligula. Donec
          bibendum vulputate erat, ac fringilla mi finibus nec. Donec ac dolor
          sed dolor porttitor blandit vel vel purus. Fusce vel malesuada ligula.
          Nam quis vehicula ante, eu finibus est. Proin ullamcorper fermentum
          orci, quis finibus massa. Nunc lobortis, massa ut rutrum ultrices,
          metus metus finibus ex, sit amet facilisis neque enim sed neque.
          Quisque accumsan metus vel maximus consequat. Suspendisse lacinia
          tellus a libero volutpat maximus.
        </Typography>
      </div>
    </div>
  );
}