React - 我无法停止在表格中传播标签点击

IT技术 reactjs
2021-05-06 12:56:10

在下面的例子中,我有一个简单的<table>,里面有一个复选框。我在 td、tr 和复选框上有点击事件。我希望能够单击复选框并停止冒泡到 td 和 tr。一个简单的“event.stopPropagation()”效果很好。

问题是,如果我想<label>使用“htmlFor”将 a 连接到复选框,则单击标签时事件不会停止冒泡(即使单击复选框本身仍然按预期工作)。更奇怪的是,冒泡似乎以奇怪的顺序发生(就像最后收到复选框点击一样!)。

这是代码:

var Hello = React.createClass({
  func1(e){
    console.log('tr was clicked')
  },
  func2(e){
    console.log('td was clicked')
  },
  func3(e){
    e.stopPropagation();
    console.log('Checkbox was clicked')
  },
  render: function() {
    return <table>
        <tbody>
        <tr onClick={this.func1}>
          <td onClick={this.func2}>
            <input id="thing" type="checkbox" onClick={this.func3} />                                   
            <label htmlFor="thing"> label for checkbox</label>
          </td>
        </tr>
      </tbody>
    </table>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

...这是小提琴:https : //jsfiddle.net/69z2wepo/52785/ (查看点击事件的控制台)

3个回答

label没有一个单击处理的它自己的,并不能阻止传播,所以当您单击label正常事件冒泡发生。这意味着以正确的顺序调用所有父级的事件处理程序。此外,由于htmlFor中,checkbox单击处理程序也被触发,但不作为事件冒泡的一部分。

为了解决这个问题,添加一个单独的点击处理程序到label只包含.stopPropgation()演示):

var Hello = React.createClass({
  func1(e){
    console.log('tr was clicked')
  },
  func2(e){
    console.log('td was clicked')
  },
  func3(e){
    e.stopPropagation();
    console.log('Checkbox was clicked')
  },
  stopLabelPropagation(e) {
    e.stopPropagation();
  },
  render: function() {
    return <table>
        <tbody>
        <tr onClick={this.func1}>
          <td onClick={this.func2}>
            <input id="thing" type="checkbox" onClick={this.func3} />                                     
            <label htmlFor="thing" onClick={ this.stopLabelPropagation }>label for checkbox</label>
          </td>
        </tr>
      </tbody>
    </table>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

尝试用跨度包装并添加evt.stopPropagation()到跨度的 onClick

<span onClick={evt => evt.stopPropagation()}>
   <input id="thing" type="checkbox" onClick={this.func3} />                                   
   <label htmlFor="thing"> label for checkbox</label>
</span>

只需在标签上添加一个 onClick,使用相同的功能绑定就可以了。这是代码和相关的 JSBin:https ://jsbin.com/caneqi/2/edit ? html,js,output

var Hello = React.createClass({
  func1(e){
    console.log('tr was clicked')
  },
  func2(e){
    console.log('td was clicked')
  },
  func3(e){
    e.stopPropagation();
    console.log('Checkbox was clicked')
  },
  render: function() {
    return <table>
        <tbody>
        <tr onClick={this.func1}>
          <td onClick={this.func2}>
            <input id="thing" type="checkbox" onClick={this.func3} />                                   
            <label htmlFor="thing" onClick={this.func3}> label for checkbox</label>
          </td>
        </tr>
      </tbody>
    </table>;
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);