【问题标题】:React - Prevent Event Trigger on Parent From ChildReact - 防止父子事件触发
【发布时间】:2016-09-30 19:33:33
【问题描述】:

我有这种情况,当单击父元素时,它会翻转以显示具有不同颜色的子元素。不幸的是,当用户点击其中一种颜色时,也会触发父级的“点击”事件。

如何在点击子元素时停止父元素的事件触发?

我想知道的可能解决方案:

  1. CSS?
    单击子项时将pointer-events : none 类附加到父项。但是,这意味着稍后需要清除父级的 pointer-events 类。

  2. 使用参考
    记录父元素Reactref 并单击子元素,将event.target 与参考进行比较?我不喜欢这个,因为我不喜欢全局ref

非常感谢您的想法和更好的解决方案。问题是: 单击子项时如何停止父项上的事件触发?

【问题讨论】:

    标签: javascript css reactjs events dom-events


    【解决方案1】:

    你可以使用stopPropagation

    stopPropagation - 防止当前事件在 冒泡阶段

    var App = React.createClass({
      handleParentClick: function (e) { 
        console.log('parent');
      },
    
      handleChildClick: function (e) {
        e.stopPropagation();
        console.log('child');
      },
    
      render: function() {
        return <div>
          <p onClick={this.handleParentClick}>
            <span onClick={this.handleChildClick}>Click</span>
          </p>
        </div>;
      }
    });
    
    ReactDOM.render(<App />, document.getElementById('root'));
    <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>
    <div id="root"></div>

    【讨论】:

    • 当内部孩子是 React Native 中的按钮时不起作用。
    【解决方案2】:

    我想在 props 上调用函数,但同时又想停止从子到父的事件传播,这是它的处理方式

    class LabelCancelable extends Component {
    
      handleChildClick(e) {
        e.stopPropagation()
      }
      closeClicked(e, props) {
        e.stopPropagation();
        props.onCloseClicked()
      }
    
      render() {
        const {displayLabel} = this.props;
        return (
          <span className={ "label-wrapper d-inline-block pr-2 pl-2 mr-2 mb-2" } onClick={ this.handleChildClick }>
              <button type="button" className="close cursor-pointer ml-2 float-right" aria-label="Close"
                  onClick={(e) => this.closeClicked(e, this.props) }>
                  <span aria-hidden="true">&times;</span>
              </button>
              <span className="label-text fs-12">
                { displayLabel }
              </span>
          </span>
        );
      }
    }
    
    export default LabelCancelable;
    

    【讨论】:

      【解决方案3】:

      另一种解决方案是将以下内容附加到父事件回调:

      if(event.target == event.currentTarget){
        event.stopPropagation()
        ....
      }
      

      通过这种方式,您可以拦截源自附加 DOM 节点的事件,并将不相关的事件转发到下一个节点。

      【讨论】:

        【解决方案4】:

        我在 React 中遇到了同样的问题,并使用下面的解决方案解决了它:

        if(e.currentTarget != e.target ) return;
        .......
        

        【讨论】:

          【解决方案5】:

          我在使用 Material-UI DataGrid 时遇到了这个问题,并使用它解决了这个问题:

          event.defaultMuiPrevented = true;

          例如:

          <DataGrid
            onCellDoubleClick={(params, event) => {
              if (!event.ctrlKey) {
                event.defaultMuiPrevented = true;
              }
            }}
            {...data}
          />
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-09-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-03
            • 1970-01-01
            • 2011-01-22
            相关资源
            最近更新 更多