【问题标题】:React Javascript onclick outside divReact Javascript onclick 在 div 之外
【发布时间】:2019-07-26 21:23:24
【问题描述】:

我正在开发一个网站,目前我有一个用于注销的 svg 图标。 单击图标时,会弹出一个带有注销选项的叠加层。当用户单击注销时,它应该执行某些操作,并且当用户单击 div 覆盖之外时应该隐藏。我没能做到这一点。

我尝试使用 tabIndex 将焦点放在 div 上,但随后退出选项不再可点击。

Header.js

 import React, { Component } from "react";
    import ReactDOM from "react-dom";
    class MainHeader extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          logOutShown: false
        };
      }
    render() {
    var guiResult = [];
    if (this.state.logOutShown) {
      guiResult.push(
        <div className="Login__Overlay__Frame">
          <div className="User__Login__Overlay">
          <div className="Login__Content" tabIndex="1" onFocus={this.alerting.bind(this)} onBlur={this.toggleOverlay.bind(this)}>Signout</div>
          </div>
        </div>
      );
    }

    return (
            <div className="Header__Icon">
              <div className="Icons__Log__In" tabIndex="0" onClick={this.validate.bind(this)} onBlur={this.toggleOverlay.bind(this)}/>
              {guiResult}
            </div>
    );
  }

  toggleOverlay(){
    console.log("toggle overlay");
    this.setState({ logOutShown: false});
  }

  validate() {
    console.log("validate:");
    this.setState(
      {
        logOutShown: true
      }
    );
  }

【问题讨论】:

  • 您可以将处理程序添加到覆盖&lt;div className="User__Login__Overlay" onClick={this.toggleOverlay.bind(this)}&gt;
  • 可以查看点击overlay,但是有问题!!。当您单击叠加层内的任何内容时,它也会拾取它。我倾向于做的是创建一个组件来做overlay,overlay里面有一个容器,这个容器附加到onClick并调用event.stopPropagation()。然后,这将停止点击您的内容,触发叠加层上的事件。
  • @Keith 我现在将通过创建一个新的叠加组件来尝试一下。可能是你能提供我新组件的整体结构看起来像我在这个“覆盖层内部有一个容器,这个容器附加到 onClick 并调用 event.stopPropagation()”
  • @Kirill 正如 Keith 所说,它不起作用。
  • 我看看能不能快速敲出一个sn-p。给我们 10..

标签: javascript html reactjs onclick hide


【解决方案1】:

这是一个简单的例子,我在这里使用 React 钩子而不是类,但你也可以使用类..

主要部分是容器 div 上的 onClick,如果您运行下面的示例并单击对话框,它不会关闭它,但单击叠加层会。

容器 div 上的 e.stopPropagation() 是阻止内容上的事件触发叠加层上的事件的原因。不使用stopPropagation,另一种选择是检查覆盖onClick 内的targetcurrentTarget..

const {useState} = React;


function Overlay(props) {
  const {contents} = props;
  const [open, setOpen] = useState(true);
  if (open) {
    return <div className="overlay" onClick={() => setOpen(false)}>
      <div onClick={(e) => {
        //stop clicks getting to the overlay
        e.stopPropagation();
      }}className="overlay-container">
        {contents()}
      </div>
    </div>
  }
  return null;
}


ReactDOM.render(<React.Fragment>
  This is some content to overlay.<br/>
  for testing..
  <Overlay contents={() =>
    <div>This is the contents, clicking here wont effect ovelay</div>
  }/>
</React.Fragment>, document.querySelector('#mount'));
.overlay {
  position: fixed;
  background-color: rgba(100,100,100,0.5);
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
}

.overlay-container {
  border: 1px solid black;
  background-color: white;
  position: absolute;
  top: 30px;
  left: 30px;
  width: 200px;
  height: 80px;
  padding: 5px;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="mount"></div>

【讨论】:

    【解决方案2】:

    您可以使用这样一个编写良好的库:react-outside-click-handler

    示例:

    import OutsideClickHandler from 'react-outside-click-handler';
    
    function MyComponent() {
      return (
        <OutsideClickHandler
          onOutsideClick={() => {
            alert('You clicked outside of this component!!!');
          }}
        >
          Hello World
        </OutsideClickHandler>
      );
    }
    

    【讨论】:

      【解决方案3】:

      使用反应参考https://reactjs.org/docs/refs-and-the-dom.html#creating-refs

      您检查事件的target 并将其用于show/hide 退出按钮。

      在安装组件时添加事件监听器。

      componentWillMount() { document.addEventListener("click", this.handleClickOutside, false); }
      

      在安装组件时移除事件监听器。

      componentWillUnmount() { document.removeEventListener("click", this.handleClickOutside, false); }
      

      检查外部点击类似这样的东西

      handleClickOutside(e) {
          if(this.submitPopoverRef.contains(e.target)) {
              // the click happened in the component
              // code to handle the submit button
              // submit();
              return;
          } 
      
          // click happened outside the component
          // hide the popover
          this.handleClick(); // set the state false
      }
      
      <div ref={node => this.submitPopoverRef = node}> 
      ... Your code here...
      
      </div>
      

      【讨论】:

        【解决方案4】:

        根据@keith 的回答: 使用 React 钩子和类: 假设有父 div 和子 div,您希望父 div 仅在点击不在子 div 内时处理点击:

        const clickedParent = () => {};
        const clickedChild = () => {};

        <div onClick={clickedParent}>
          <div className="selc-hd-so-remove" onClick={e=> { e.stopPropagation(); clickedChild(); }} > Child Div Clicked</div>
        </div>
        Parent Div Clicked
        </div>

        【讨论】:

          猜你喜欢
          • 2015-06-09
          • 1970-01-01
          • 2011-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-30
          • 2018-07-15
          • 2018-01-03
          相关资源
          最近更新 更多