显示 Material-ui 弹出窗口时元素未处理事件

Elements not processing event when Material-ui Popup is displayed

我有一个简单的 material-ui List 包含 ListItem 个元素。

我希望 Popover 出现在我将鼠标放在 ListItem 上的任何内容旁边。为此,我正在使用 mouseEnter 事件。在其处理程序中,我将 Popover 锚元素 设置为鼠标指针当前位于上方的 ListItem

这适用于我悬停的第一个元素。但是,因为 Popover 本质上以 "modal" 类型的方式运行,所以当我移动到列表中的另一个 ListItem 时,它的 mouseEnter 事件不会被触发。

我已经处理这个问题几个小时了,但找不到解决方法?

这是一个 CodeSandbox。尝试将鼠标悬停在其中一个 ListItem 上,您将在控制台中看到输出。尝试移动到另一个,但没有任何反应。

import React, { useState } from "react";
import "./styles.css";
import { List, ListItem, ListItemText, Popover } from "@material-ui/core";

export default function App() {
  const [popoverAnchorElement, setPopoverAnchorElement] = useState(null);
  const handleMouseEnter = event => {
    console.log("onMouseEnter - " + event.currentTarget.textContent);
    setPopoverAnchorElement(event.currentTarget);
  };

  const handleClose = (event, index) => {
    setPopoverAnchorElement(null);
  };

  let isPopoverOpen = Boolean(popoverAnchorElement);
  return (
    <div className="App">
      <List style={{ maxWidth: "100px" }}>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem1</ListItemText>
        </ListItem>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem2</ListItemText>
        </ListItem>
        <ListItem button>
          <ListItemText onMouseEnter={handleMouseEnter}>ListItem3</ListItemText>
        </ListItem>
      </List>
      <Popover
        open={isPopoverOpen}
        onClose={handleClose}
        anchorEl={popoverAnchorElement}
        anchorOrigin={{
          vertical: "top",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
      >
        <ListItem button>
          <ListItemText>ListItemInPopover</ListItemText>
        </ListItem>
      </Popover>
    </div>
  );
}


Popover 组件覆盖整个屏幕 (position:fixed; left:0; top:0; right:0; bottom:0; z-index:1300),有效地阻止来自下方项目的任何鼠标事件。

您可以尝试绕过这一点,例如将 pointer-events:none; 添加到其覆盖元素将允许光标事件通过它。

但是,使用一个只为一个小菜单项挡住整个视口的组件对我来说似乎很奇怪,而且可能是一场艰苦的战斗。

同一个库中有一个名为 Popper 的类似组件,它可能更适合您的需要。在这里您可以看到我已将您的 Popover 转换为 Popper,您得到的结果更像您期望的那样。 (请注意,我在代码沙箱中向该元素添加了一些 CSS 以使其更清晰。)

  <Popper
    open={isPopoverOpen}
    onClose={handleClose}
    anchorEl={popoverAnchorElement}
    className="popper-item"
  >
    <ListItem button>
      <ListItemText>ListItemInPopover</ListItemText>
    </ListItem>
  </Popper>

https://codesandbox.io/s/keen-smoke-x8tu7

我会注意到文档指出,如果您单击远离这些项目,Popper 将不会自动关闭,但可以添加。

您还可以查看 MenuList 组件,它在后台使用 Popper,但也为您处理一些状态。