【问题标题】:How to Make Material-UI Menu based on Hover, not Click如何基于悬停而不是单击制作 Material-UI 菜单
【发布时间】:2019-03-23 21:16:11
【问题描述】:

我正在使用 Material-UI 菜单。 它应该按原样工作,但只是使用鼠标悬停,而不是单击。 这是我的代码链接:https://codesandbox.io/embed/vn3p5j40m0

以下是我尝试过的代码。它可以正确打开,但在鼠标移开时不会关闭。

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

function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    setAnchorEl(event.currentTarget);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <div>
      <Button
        aria-owns={anchorEl ? "simple-menu" : undefined}
        aria-haspopup="true"
        onClick={handleClick}
        onMouseEnter={handleClick}
      >
        Open Menu
      </Button>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={handleClose}
        onMouseLeave={handleClose}
      >
        <MenuItem onClick={handleClose}>Profile</MenuItem>
        <MenuItem onClick={handleClose}>My account</MenuItem>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
    </div>
  );
}

export default SimpleMenu;

【问题讨论】:

  • 菜单根据传递给它的open 属性打开。您可以以任何您想要的方式触发它。如果您无法通过悬停使其工作,请分享您尝试但不起作用的代码。
  • 您好,感谢您的回复。我已将链接添加到我的代码中。将等待您的反馈。
  • 它似乎有效。有什么问题?
  • 我希望当鼠标光标悬停在菜单外时菜单消失,而不是点击背景。

标签: reactjs material-ui


【解决方案1】:

下面的代码似乎可以正常工作。与您的沙盒相比,主要变化是在按钮上使用onMouseOver={handleClick} 而不是onMouseEnter。如果没有此更改,如果鼠标不在菜单的一部分所在的位置,它将无法可靠地打开。另一个更改是使用MenuListProps={{ onMouseLeave: handleClose }}。直接在Menu 上使用onMouseLeave 不起作用,因为菜单包括一个覆盖层作为菜单的一部分,利用Modal 并且鼠标永远不会“离开”覆盖层。 MenuList 是 Menu 中显示菜单项的部分。

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

function SimpleMenu() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    if (anchorEl !== event.currentTarget) {
      setAnchorEl(event.currentTarget);
    }
  }

  function handleClose() {
    setAnchorEl(null);
  }

  return (
    <div>
      <Button
        aria-owns={anchorEl ? "simple-menu" : undefined}
        aria-haspopup="true"
        onClick={handleClick}
        onMouseOver={handleClick}
      >
        Open Menu
      </Button>
      <Menu
        id="simple-menu"
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={handleClose}
        MenuListProps={{ onMouseLeave: handleClose }}
      >
        <MenuItem onClick={handleClose}>Profile</MenuItem>
        <MenuItem onClick={handleClose}>My account</MenuItem>
        <MenuItem onClick={handleClose}>Logout</MenuItem>
      </Menu>
    </div>
  );
}

export default SimpleMenu;

【讨论】:

  • 如果菜单列表弹出在按钮下方,而不是覆盖在按钮上,并且您甚至没有将鼠标悬停在菜单列表上并将鼠标悬停在按钮上怎么办?
  • 可能需要大量工作才能以稳健的方式执行此操作。我并没有声称我的答案是可靠的——只是它工作正常并为您提供了一个起点。
  • 这个代码例子有个很大的缺陷,如果我们把弹窗放在按钮下面,滚动到按钮上触发弹窗,然后左右滚动,弹窗不会关闭
  • 此外,如果两个这样的按钮彼此靠近,将鼠标从一个悬停到另一个将导致第一个不关闭。 (我知道@RyanCogswell 说他自己并没有声称它很强大,所以只是说)。
【解决方案2】:

使用带有菜单项的交互式 HTML 工具提示可以完美地工作,而无需您必须单击以查看菜单项。

这是material UI v.4 的示例。

import React from 'react';
import { withStyles, Theme, makeStyles } from '@material-ui/core/styles';
import Tooltip from '@material-ui/core/Tooltip';
import { MenuItem, IconButton } from '@material-ui/core';
import MoreVertIcon from '@material-ui/icons/MoreVert';
import styles from 'assets/jss/material-dashboard-pro-react/components/tasksStyle.js';

// @ts-ignore
const useStyles = makeStyles(styles);

const LightTooltip = withStyles((theme: Theme) => ({
  tooltip: {
    backgroundColor: theme.palette.common.white,
    color: 'rgba(0, 0, 0, 0.87)',
    boxShadow: theme.shadows[1],
    fontSize: 11,
    padding: 0,
    margin: 4,
  },
}))(Tooltip);

interface IProps {
  menus: {
    action: () => void;
    name: string;
  }[];
}
const HoverDropdown: React.FC<IProps> = ({ menus }) => {
  const classes = useStyles();
  return (
    <div>
      <LightTooltip
        interactive
        title={
          <React.Fragment>
            {menus.map((item) => {
              return <MenuItem onClick={item.action}>{item.name}</MenuItem>;
            })}
          </React.Fragment>
        }
      >
        <IconButton
          aria-label='more'
          aria-controls='long-menu'
          aria-haspopup='true'
          className={classes.tableActionButton}
        >
          <MoreVertIcon />
        </IconButton>
      </LightTooltip>
    </div>
  );
};

export default HoverDropdown;

用法:

<HoverDropdown
        menus={[
          {
            name: 'Item 1',
            action: () => {
              history.push(
                codeGeneratorRoutes.getEditLink(row.values['node._id'])
              );
            },
          },{
            name: 'Item 2',
            action: () => {
              history.push(
                codeGeneratorRoutes.getEditLink(row.values['node._id'])
              );
            },
          },{
            name: 'Item 3',
            action: () => {
              history.push(
                codeGeneratorRoutes.getEditLink(row.values['node._id'])
              );
            },
          },{
            name: 'Item 4',
            action: () => {
              history.push(
                codeGeneratorRoutes.getEditLink(row.values['node._id'])
              );
            },
          },
        ]}
      />

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 2018-07-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2018-10-11
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多