reactjs - Material UI ClickAwayListener 在单击自身时关闭

标签 reactjs material-ui

我有下面的显示侧边栏开关,它显示在 Popper 中。因此,理想情况下,如果您单击其他位置(Popper 元素之外),Popper 应该消失。如果您在 Popper 元素内部单击,它不应该去任何地方。当我单击“开关”或“显示侧边栏”文本时,该 Popper 就会消失。我用 <div> 包裹波普尔这也没有帮助。

波普尔 https://material-ui.com/api/popper/

切换https://material-ui.com/api/switch/

ClickAwayListener https://material-ui.com/utils/click-away-listener/

下面是波普尔代码

<ClickAwayListener onClickAway={this.handleClickAway}>
      <div>
        <Popper className={classes.popper} id={id} open={open} placement="bottom-end" anchorEl={anchorEl} transition>
          {({ TransitionProps }) => (
            <Fade {...TransitionProps} timeout={350}>
              <Paper className={classes.SliderBox}>
                <Switch
                  checked={this.state.checkedB}
                  onChange={this.handleChange('checkedB')}
                  value="checkedB"
                  color="primary"
                  onClick={handleDrawer}
                  className={classNames(classes.menuButton, sidebar && classes.hide)}
                />
                Display Sidebar
              </Paper>
            </Fade>
          )}
        </Popper>
        </div>
       </ClickAwayListener>

我这里有示例(虽然我无法让它工作,但我不知道为什么它在点击时出错) https://codesandbox.io/s/8pkm3x1902

enter image description here

最佳答案

默认情况下,Popper利用portal ( https://github.com/mui-org/material-ui/blob/v4.11.0/packages/material-ui/src/Popper/Popper.js#L202 ) 将其内容呈现在 DOM 的单独部分(作为 <body> 元素的直接子元素),其中 Popper 元素位于 DOM 的单独部分中。元素岛。这意味着您有 ClickAwayListener周围空无一人<div> ,因此任意位置的单击(包括 Popper 内容内)将被视为在该空 <div> 之外。 .

移动ClickAwayListener直接围绕Fade (而不是围绕 Popper )确保它围绕 Popper 呈现的实际内容.

这是一个基于您的沙箱的工作示例:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Popper from "@material-ui/core/Popper";
import Fade from "@material-ui/core/Fade";
import Paper from "@material-ui/core/Paper";
import Switch from "@material-ui/core/Switch";
import Avatar from "@material-ui/core/Avatar";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";

class App extends Component {
  state = {
    anchorEl: null,
    open: false,
    checkedB: true
  };

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

  handleChange = (name) => (event) => {
    this.setState({
      [name]: event.target.checked
    });
  };

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

  render() {
    const { anchorEl, open } = this.state;
    const { handleDrawer } = this.props;
    const id = open ? "simple-popper" : null;
    return (
      <div className="App">
        asdsadsa
        <Avatar
          alt="Test"
          src="https://www.nretnil.com/avatar/LawrenceEzekielAmos.png"
          style={{ margin: "0 10px" }}
          onClick={this.handleClick}
        />
        <div>
          <Popper
            id={id}
            open={open}
            placement="bottom-end"
            anchorEl={anchorEl}
            transition
          >
            {({ TransitionProps }) => (
              <ClickAwayListener onClickAway={this.handleClickAway}>
                <Fade {...TransitionProps} timeout={350}>
                  <Paper //className={classes.SliderBox}
                  >
                    <Switch
                      checked={this.state.checkedB}
                      onChange={this.handleChange("checkedB")}
                      value="checkedB"
                      color="primary"
                      onClick={handleDrawer}
                    />
                    Display Sidebar
                  </Paper>
                </Fade>
              </ClickAwayListener>
            )}
          </Popper>
        </div>
      </div>
    );
  }
}

export default App;

ReactDOM.render(<App />, document.getElementById("root"));

Edit Popper ClickAwayListener

在 v4 中 ClickAwayListener支持识别元素位于其 React 元素树中,即使它们是在门户中呈现的(最初的问题是针对 v3 的),但放置 ClickAwayListener 仍然更可靠。里面Popper而不是在外面避免ClickAwayListener点击打开Popper这使得它看起来像 Popper无法工作,因为它立即关闭(例如: https://codesandbox.io/s/popper-clickawaylistener-forked-x4j0l?file=/src/index.js )。

关于reactjs - Material UI ClickAwayListener 在单击自身时关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55143914/

相关文章:

node.js - http POST 上的 net::ERR_SSL_PROTOCOL_ERROR 到 express 服务器

javascript - React 有没有办法在不构建虚拟树的情况下更新 DOM?

html - onMouseLeave for Popover with hiderBackdrop parameter (material ui)

reactjs - React Jest 导致 "SyntaxError: Unexpected token ."

javascript - TableRow Material-UI 之间的间距

reactjs - 我无法更改全局背景 Material ui

reactjs - Typeface-roboto 的用途是什么?

javascript - 然后在 Promise 内部进行异步/等待

javascript - webpack 无法解析 node_modules Material 图标

javascript - Material-UI 复选框不适用于 Redux 商店