在下面的例子中,我有一个简单<table>的内部有一个复选框.我在td,tr和复选框上点击了事件.我希望能够单击复选框并停止冒泡到td和tr.一个简单的"event.stopPropagation()"效果很好.
问题是,如果我想<label>使用"htmlFor" 将a连接到复选框,则单击标签时事件不会停止冒泡(即使它仍然按预期工作,单击复选框本身).甚至更奇怪的是,冒泡似乎发生在一个奇怪的顺序(如最后收到Checkbox点击!).
这是代码:
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')
);
Run Code Online (Sandbox Code Playgroud)
...这里是小提琴:https: //jsfiddle.net/69z2wepo/52785/ (查看控制台的点击事件)
在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')
);
Run Code Online (Sandbox Code Playgroud)
尝试用 span 包裹并添加evt.stopPropagation()到 span 的 onClick
<span onClick={evt => evt.stopPropagation()}>
<input id="thing" type="checkbox" onClick={this.func3} />
<label htmlFor="thing"> label for checkbox</label>
</span>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2775 次 |
| 最近记录: |