Как продолжать показывать «всплывающее окно» при наведении курсора на якорь и «всплывающее окно»?

Вот в этом примере material-uihttps://material-ui.com/utils/popover/#mouse-over-interaction

Выполните следующие действия для примера material-uihttps://material-ui.com/utils/popover/#mouse-over-interaction

  1. В приведенном выше примере держите мышь на тексте Hover with a Popover. --- вы видите popover

  2. Попробуйте подвести указатель мыши к 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

что вы хотите мне непонятно?? можешь немного по другому объяснить, что именно ты хочешь?

Ahm. 15.02.2019 09:36

Обновлено. Вы можете проверить сейчас?

Coder 15.02.2019 09:42

Я считаю, что проблема не получает внимания. Если вы используете onClick в качестве триггера, вы обнаружите, что вообще не можете щелкнуть всплывающее окно.

doublejosh 24.03.2020 21:29
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
17
3
7 049
4

Ответы 4

кодыпесочница DEMO

Я взломал его, добавив функцию setTimeout() для события onMouseLeave... Я уверен, что есть и другие способы сделать это, но это зависит от ваших конкретных потребностей.

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

Поскольку React может размонтировать компонент в середине взаимодействия, это может быть не лучшим подходом. Наименее было бы добавление clearTimeout при размонтировании, но это тоже не оптимальный подход.

Lucas Kauz 06.07.2020 22:36

У меня была та же проблема, я не нашел ответа, и мне потребовалось некоторое время, чтобы понять, как это исправить.

На самом деле проблема возникает из-за 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 MyComponent
codeandbox.io/s/material-demo-79he1 для рабочего примера.
streetlogics 07.05.2020 23:27
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>
  );
}

Спасибо за этот ответ. Будьте осторожны, используя pointerEvents: 'none' и pointerEvents: 'auto', чтобы они работали правильно.

Другие вопросы по теме