代码之家  ›  专栏  ›  技术社区  ›  Jimmy

仅当事件位于具有特定类的dom元素之外时才触发该事件

  •  0
  • Jimmy  · 技术社区  · 7 年前

    我有一个监听点击的事件监听器。如果这些点击在给定的dom元素之外,则调用某个函数(在本例中, handleClick ).

    现在,函数 仅当事件目标不是具有 this.setWrapper

    我在想我怎样才能防止 手舔 .boxTwo .

    注意,我不想通过向的div添加ref来实现这一点 第二箱 ,但通过查询DOM来识别在类名为“boxTwo”的div中发生的任何单击。谢谢!

    class App extends React.Component {
      constructor() {
        super();
        this.state = {onClick: false};
        this.setWrapperRef = this.setWrapperRef.bind(this);
        this.handleClick = this.handleClick.bind(this);
      }
    
      componentDidMount() {
        document.addEventListener('mousedown', this.handleClick);
      }
    
      componentWillUnmount() {
        document.removeEventListener('mousedown', this.handleClick);
      }
    
      setWrapperRef(node) {
        this.wrapperRef = node;
      }
    
      handleClick(event) {
        if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
          this.setState({onClick: !this.state.onClick});
        }
      }
    
      render() {
        return (
          <section>
            <div className="boxOne" ref={this.setWrapperRef} />
            <div className="boxTwo" />
            <div>{this.state.onClick ? "On" : "Off"}</div>
          </section>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'));
    .boxOne {
      height: 100px;
      width: 100px;
      background: pink;
    }
    
    .boxTwo {
      margin: 30px;
      height: 50px;
      width: 70px;
      border: solid black 2px;
      background: orange;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="app"></div>
    2 回复  |  直到 7 年前
        1
  •  1
  •   aquiseb    7 年前
    • 你只需要检查一下 event.target.className 不等于 boxTwo
    • boxOne 班级。
    • 如果您想在完全没有类名的所有情况下触发,您可以在条件语句中使用这个: !event.target.className

    多一点,为了可读性,我会这样做的

    handleClick(event) {
    
        // The ones that don't trigger
        const disabledTriggers = ['boxOne', 'boxTwo'];
    
        // Ok if no class contained in our event classList are disabled
        const ok = !disabledTriggers.some(c => event.target.classList && event.target.classList.contains(c))
        if(ok) {
          this.setState({onClick: !this.state.onClick});
        }
      }
    

    class App extends React.Component {
      constructor() {
        super();
        this.state = {onClick: false};
        this.setWrapperRef = this.setWrapperRef.bind(this);
        this.handleClick = this.handleClick.bind(this);
      }
    
      componentDidMount() {
        document.addEventListener('mousedown', this.handleClick);
      }
    
      componentWillUnmount() {
        document.removeEventListener('mousedown', this.handleClick);
      }
    
      setWrapperRef(node) {
        this.wrapperRef = node;
      }
    
      handleClick(event) {
        
        if (event.target.className !== 'boxTwo' && this.wrapperRef && !this.wrapperRef.contains(event.target)) {
          this.setState({onClick: !this.state.onClick});
        }
      }
    
      render() {
        return (
          <section>
            <div className="boxOne" ref={this.setWrapperRef} />
            <div className="boxTwo" />
            <div>{this.state.onClick ? "On" : "Off"}</div>
          </section>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'));
    .boxOne {
      height: 100px;
      width: 100px;
      background: pink;
    }
    
    .boxTwo {
      margin: 30px;
      height: 50px;
      width: 70px;
      border: solid black 2px;
      background: orange;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="app"></div>
        2
  •  0
  •   PassionInfinite Matt Busche    7 年前

    让我解释一下我做了什么。

    1. 添加了一个状态来维护其上的元素的类 我们不想有一次。
    2. 我要检查一下 event.target.classList
    3. 如果不存在,则在组件外部单击。希望如此 帮助你。

      如果您有任何疑问,请在下面发表评论。我想尽我所能帮助你。

    class App extends React.Component {
      constructor() {
        super();
        this.state = {onClick: false, wrapperRefs: ['boxOne', 'boxTwo']};
        this.handleClick = this.handleClick.bind(this);
      }
    
      componentDidMount() {
        document.addEventListener('mousedown', this.handleClick);
      }
    
      componentWillUnmount() {
        document.removeEventListener('mousedown', this.handleClick);
      }
    
      handleClick(event) {
        const classes = event.target.classList;
        const exists = this.state.wrapperRefs.some(ref => classes.contains(ref));
        if(!exists) {
          this.setState({onClick: !this.state.onClick});
        }
      }
    
      render() {
        return (
          <section>
            <div className="boxOne container" />
            <div className="boxTwo" />
            <div>{this.state.onClick ? "On" : "Off"}</div>
          </section>
        );
      }
    }
    
    ReactDOM.render(<App />, document.getElementById('app'));
    .boxOne {
      height: 100px;
      width: 100px;
      background: pink;
    }
    
    .boxTwo {
      margin: 30px;
      height: 50px;
      width: 70px;
      border: solid black 2px;
      background: orange;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="app"></div>