繁体   English   中英

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

[英]Trigger an event only if it is outside of a dom element that has a specific class

我有一个事件监听器,可以监听点击。 如果这些点击不在给定的dom元素之外,则将调用某个函数(在这种情况下为handleClick )。

现在,仅当事件目标不是具有this.setWrapper引用的事件目标时,才调用handleClick函数。

我想知道如果我也碰巧单击.boxTwo如何防止handleClick被调用。

注意,我要这样做不是通过在.boxTwo的div中添加引用,而是通过查询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> 

  • 您只需要检查event.target.className是否不等于boxTwo ,如下所示。
  • 如果目标具有boxOne类,则可以使用相同的“技术”来防止调用函数。
  • 如果要在根本没有className的所有情况下触发,则可以在条件语句中使用以下代码: !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> 

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

  1. 添加了一种状态来维护我们不想在其上单击的元素的类。
  2. 向boxOne类添加了一个以上的容器类,以检查这是否成立,即使我们有多个类也是如此。
  3. 我检查了event.target.classList (它返回当前目标的类列表),并检查是否有任何来自classList的人存在于状态wrapperRefs中。
  4. 如果不存在,则在组件外部单击。 我希望这可以帮助你。

    如果您有任何疑问,请在下面评论。 我想为您提供尽可能多的帮助。

 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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM