【问题标题】:How to keep showing the 'popover' on hovering on the anchorEl and 'popover' as well?如何在悬停在 anchorEl 和“popover”上时继续显示“popover”?
【发布时间】:2019-07-09 08:33:23
【问题描述】:

这里是material-uihttps://material-ui.com/utils/popover/#mouse-over-interaction的例子

对于示例 material-ui https://material-ui.com/utils/popover/#mouse-over-interaction,请按照以下步骤操作

  1. 在上面的例子中,将鼠标保持在文本Hover with a Popover. --- 你看到popover

  2. 试着把你的鼠标移到popover附近——popover消失了对吧? 但即使我将鼠标悬停在 popover

  3. 上,我也想显示弹出框

只有当用户没有悬停在popoverHover with a Popover.(基本上是anchorEl)上时才会使弹出框消失

我正在从他们的演示中复制代码

  import React from 'react';
    import PropTypes from 'prop-types';
    import Popover from '@material-ui/core/Popover';
    import Typography from '@material-ui/core/Typography';
    import { withStyles } from '@material-ui/core/styles';

    const styles = theme => ({
      popover: {
        pointerEvents: 'none',
      },
      paper: {
        padding: theme.spacing.unit,
      },
    });

    class MouseOverPopover extends React.Component {
      state = {
        anchorEl: null,
      };

      handlePopoverOpen = event => {
        this.setState({ anchorEl: event.currentTarget });
      };

      handlePopoverClose = () => {
        this.setState({ anchorEl: null });
      };

      render() {
        const { classes } = this.props;
        const { anchorEl } = this.state;
        const open = Boolean(anchorEl);

        return (
          <div>
            <Typography
              aria-owns={open ? 'mouse-over-popover' : undefined}
              aria-haspopup="true"
              onMouseEnter={this.handlePopoverOpen}
              onMouseLeave={this.handlePopoverClose}
            >
              Hover with a Popover.
            </Typography>
            <Popover
              id="mouse-over-popover"
              className={classes.popover}
              classes={{
                paper: classes.paper,
              }}
              open={open}
              anchorEl={anchorEl}
              anchorOrigin={{
                vertical: 'bottom',
                horizontal: 'left',
              }}
              transformOrigin={{
                vertical: 'top',
                horizontal: 'left',
              }}
              onClose={this.handlePopoverClose}
              disableRestoreFocus
            >
              <Typography>I use Popover.</Typography>
            </Popover>
          </div>
        );
      }
    }

    MouseOverPopover.propTypes = {
      classes: PropTypes.object.isRequired,
    };

    export default withStyles(styles)(MouseOverPopover);

我需要在此处进行哪些代码更改? 你可以试试https://codesandbox.io/s/6l3wk6kv3

【问题讨论】:

  • 我不清楚你想要什么??你能解释一下你到底想要什么吗?
  • 已更新。你现在可以检查吗?
  • 我相信这个问题没有引起关注。如果你使用onClick 作为触发器,你会发现你实际上根本无法点击弹出框。

标签: javascript reactjs material-ui dom-events


【解决方案1】:

我遇到了同样的问题,没有找到任何答案,我花了一段时间才明白如何解决它。

其实问题出在pointerEvents: none 你需要在popover上防止你的onMouseEnter/onMouseLeave被同时触发。

但是你可以为你的popover pointerEvents的内容设置:auto。

然后您可以在弹出框的内容上添加一个 onMouseEnter 和一个 onMouseLeave。

这是一个更明确的例子:

import React, { useState, useRef } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { Popover } from '@material-ui/core';

const useStyles = makeStyles(theme => ({
  popover: {
    pointerEvents: 'none',
  },
  popoverContent: {
    pointerEvents: 'auto',
  },
}));

const MyComponent = ({ loading, login, wrong, clearWrongLogin }: Props) => {
  const [openedPopover, setOpenedPopover] = useState(false)
  const popoverAnchor = useRef(null);

  const popoverEnter = ({ currentTarget }) => {
    setOpenedPopover(true)
  };

  const popoverLeave = ({ currentTarget }) => {
    setOpenedPopover(false)
  };

  const classes = useStyles();

return (
    <div>
         <span
          ref={popoverAnchor}
          aria-owns="mouse-over-popover"
          aria-haspopup="true"
          onMouseEnter={popoverEnter}
          onMouseLeave={popoverLeave}
        >Hover this el !
        </span>
        <Popover
        id="mouse-over-popover"
        className={classes.popover}
        classes={{
          paper: classes.popoverContent,
        }}
        open={openedPopover}
        anchorEl={popoverAnchor.current}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'right',
        }}
        transformOrigin={{
          vertical: 'top',
          horizontal: 'left',
        }}
        PaperProps={{onMouseEnter: popoverEnter, onMouseLeave: popoverLeave}}
      >
        <div>
          My popover content...
        </div>
      </Popover>
    </div>
  );
};

export default MyComponent

【讨论】:

【解决方案2】:
import React from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  popover: {
    pointerEvents: "none"
  },
  paper: {
    pointerEvents: "auto",
    padding: theme.spacing(1)
  }
}));

export default function MouseOverPopover() {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handlePopoverOpen = event => {
    setAnchorEl(event.currentTarget);
  };

  const handlePopoverClose = () => {
    setAnchorEl(null);
  };

  const open = Boolean(anchorEl);

  return (
    <div onMouseEnter={handlePopoverOpen} onMouseLeave={handlePopoverClose}>
      <Typography
        aria-owns={open ? "mouse-over-popover" : undefined}
        aria-haspopup="true"
      >
        Hover with a Popover.
      </Typography>
      <Popover
        id="mouse-over-popover"
        className={classes.popover}
        classes={{
          paper: classes.paper
        }}
        open={open}
        anchorEl={anchorEl}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "left"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left"
        }}
        onClose={handlePopoverClose}
        disableRestoreFocus
      >
        <Typography>I use Popover.</Typography>
      </Popover>
    </div>
  );
}

【讨论】:

    【解决方案3】:

    感谢this answer。小心使用pointerEvents: 'none'pointerEvents: 'auto' 真正起作用。

    【讨论】:

      【解决方案4】:

      codesandbox DEMO

      我通过为onMouseLeave 事件添加setTimeout() 函数来破解它...我确信还有其他方法可以做到这一点,但这取决于您的具体需求

        handlePopoverClose = () => {
          setTimeout(() => { 
            this.setState({ anchorEl: null });
          }, 3000);
        };
      

      【讨论】:

      • 由于 React 可以在交互过程中卸载组件,这可能不是最好的方法。至少会在卸载时添加 clearTimeout,但也不是最佳方法。
      猜你喜欢
      • 2020-09-12
      • 2019-11-18
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多