在鼠标悬停上打开菜单,在mouseleave上关闭菜单进行反应

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在鼠标悬停上打开菜单,在mouseleave上关闭菜单进行反应相关的知识,希望对你有一定的参考价值。

我刚开始接受电镀反应。我目前正在使用material-ui和我的navBar进行反应。当我将鼠标悬停在菜单上时,会显示下拉列表。但是为了关闭下拉列表,我必须单击下拉列表的外部。我希望能够在我将鼠标悬停在下拉菜单或移动到不同的菜单选项时关闭下拉菜单(在这种情况下,应显示不同的下拉菜单)。像这样的东西:https://www.palantir.com/

我环顾四周,但没有找到解决办法。这是我得到的最接近的:Material-ui: open menu by event hover

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

编辑:我在这里重新创建了我的问题: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?"
/>
)}
答案

闪烁是由鼠标下方菜单打开引起的。当菜单打开时,鼠标不再在按钮上方,因此它会提示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;

我使用MenuListProps直接在mouseEnter本身设置mouseLeaveMenuList事件,因为Menu组件包括一堆看不见的(disply: none)过渡元素,它们对鼠标事件有奇怪的影响。 MenuList是实际显示的元素,因此直接在其上设置鼠标事件是有意义的。

你可能需要玩timeoutLength和过渡来让一切看起来都很流畅。

以上是关于在鼠标悬停上打开菜单,在mouseleave上关闭菜单进行反应的主要内容,如果未能解决你的问题,请参考以下文章

如何从 jquery 中的 2 个 div 中隐藏 mouseleave 上的 div?

半秒后使用 AngularJS 在鼠标悬停时显示子菜单

Bootstrap 下拉菜单在悬停时关闭

获取 MouseLeave 事件后鼠标悬停的第一个元素

如何保持悬停的菜单项处于打开状态,以便我可以使用 firebug 编辑它的样式?

建立一个jQuery菜单