Вот в этом примере material-uihttps://material-ui.com/utils/popover/#mouse-over-interaction
Выполните следующие действия для примера material-uihttps://material-ui.com/utils/popover/#mouse-over-interaction
В приведенном выше примере держите мышь на тексте Hover with a Popover.
--- вы видите popover
Попробуйте подвести указатель мыши к popover --- popover исчезает, верно?
Но я хочу показать всплывающее окно, даже если я наведу курсор на popover
И сделайте так, чтобы всплывающее окно исчезало только в том случае, если пользователь не зависает ни на popover, ни на Hover 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 [JS]](https://i.imgur.com/WsjO6zJb.png)


Я взломал его, добавив функцию setTimeout() для события onMouseLeave... Я уверен, что есть и другие способы сделать это, но это зависит от ваших конкретных потребностей.
handlePopoverClose = () => {
setTimeout(() => {
this.setState({ anchorEl: null });
}, 3000);
};
Поскольку React может размонтировать компонент в середине взаимодействия, это может быть не лучшим подходом. Наименее было бы добавление clearTimeout при размонтировании, но это тоже не оптимальный подход.
У меня была та же проблема, я не нашел ответа, и мне потребовалось некоторое время, чтобы понять, как это исправить.
На самом деле проблема возникает из-за pointerEvents: нет, что вам нужно во всплывающем окне, чтобы предотвратить одновременное срабатывание onMouseEnter/onMouseLeave.
Но вы можете установить для содержимого вашего всплывающего окна 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 MyComponentimport 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>
);
}
Спасибо за этот ответ. Будьте осторожны, используя pointerEvents: 'none' и pointerEvents: 'auto', чтобы они работали правильно.
что вы хотите мне непонятно?? можешь немного по другому объяснить, что именно ты хочешь?