鼠标悬停时打开菜单,鼠标悬停时关闭菜单

abi*_*jia 2 onmouseover onmouseout drop-down-menu reactjs material-ui

我刚刚开始与反应电镀。我目前正在使用material-ui进行我的navBar并做出反应。当我将鼠标悬停在菜单上时,将显示下拉菜单。但是为了关闭下拉菜单,我必须单击下拉菜单的外部。我希望能够在将鼠标悬停在下拉菜单之外或移至其他菜单选项(在这种情况下,应显示另一个下拉菜单)时关闭该下拉菜单。像这样的东西:https : //www.palantir.com/

我环顾四周,但找不到解决方案。这是我最近得到的:Material-ui:通过事件悬停打开菜单

我尝试使用相同的技术,并将其添加到我的代码中,但无济于事。有什么建议么?谢谢!

编辑:我在这里重新创建了我的问题:https : //react-xmaiyw.stackblitz.io 单击“为什么我们”时可以看到问题。

 handleClick = (event) => {
 event.preventDefault();

   this.setState({
    open: true,
    anchorEl: event.currentTarget,
   });
 };

handleRequestClose = () => {
  this.setState({
   open: false,
  });
};

render() {
return (
  <FlatButton
  onClick={this.handleClick}
  onMouseOver={this.handleClick}
  onMouseLeave={this.handleRequestClose} //When I add this line of 
     //code, it keeps flickering very fast almost as if drop-down 
     //doesn't open
  label="Why Us?"
/>
)}
Run Code Online (Sandbox Code Playgroud)

Jul*_*ont 6

闪烁是由鼠标下方菜单的打开引起的。菜单打开时,鼠标不再位于按钮上方,因此它会提示一个mouseleave事件,关闭菜单,从而使鼠标现在再次位于按钮上方,提示mouseenter事件,从而打开菜单...依此类推,等等。

您可以通过一些附加的逻辑来跟踪鼠标的位置以及超时以确保用户有时间在按钮和菜单之间转换鼠标来完成所需的操作。

import React from 'react';
import Button from 'material-ui/Button';
import Menu, { MenuItem } from 'material-ui/Menu';

const timeoutLength = 300;

class SimpleMenu extends React.Component {
  state = {
    anchorEl: null,

    // Keep track of whether the mouse is over the button or menu
    mouseOverButton: false,
    mouseOverMenu: false,
  };

  handleClick = event => {
    this.setState({ open: true, anchorEl: event.currentTarget });
  };

  handleClose = () => {
    this.setState({ mouseOverButton: false, mouseOverMenu: false });
  };

  enterButton = () => {
    this.setState({ mouseOverButton: true });
  }

  leaveButton = () => {
    // Set a timeout so that the menu doesn't close before the user has time to
    // move their mouse over it
    setTimeout(() => {
      this.setState({ mouseOverButton: false });
    }, timeoutLength);
  }

  enterMenu = () => {
    this.setState({ mouseOverMenu: true });
  }

  leaveMenu = () => {
     setTimeout(() => {
      this.setState({ mouseOverMenu: false });
     }, timeoutLength);
  }

  render() {
    // Calculate open state based on mouse location
    const open = this.state.mouseOverButton || this.state.mouseOverMenu;

    return (
      <div>
        <Button
          aria-owns={this.state.open ? 'simple-menu' : null}
          aria-haspopup="true"
          onClick={this.handleClick}
          onMouseEnter={this.enterButton}
          onMouseLeave={this.leaveButton}
        >
          Open Menu
        </Button>
        <Menu
          id="simple-menu"
          anchorEl={this.state.anchorEl}
          open={open}
          onClose={this.handleClose}
          MenuListProps={{
            onMouseEnter: this.enterMenu,
            onMouseLeave: this.leaveMenu,
          }}

        >
          <MenuItem onClick={this.handleClose}>Profile</MenuItem>
          <MenuItem onClick={this.handleClose}>My account</MenuItem>
          <MenuItem onClick={this.handleClose}>Logout</MenuItem>
        </Menu>
      </div>
    );
  }
}

export default SimpleMenu;
Run Code Online (Sandbox Code Playgroud)

我使用MenuListProps来直接在其本身上设置mouseEntermouseLeave事件,MenuList因为该Menu组件包括一堆disply: none对鼠标事件产生怪异影响的不可见()过渡元素。的MenuList是,实际上显示的是很有意义直接设置鼠标事件上的元素。

您可能需要使用timeoutLength和过渡,以使一切看起来都很流畅。