React - 防止父事件触发子事件
React - Prevent Event Trigger on Parent From Child
我遇到过这种情况,当单击父元素时,它会翻转以显示具有不同颜色的子元素。不幸的是,当用户点击其中一种颜色时,父级上的 'click' 事件也会被触发。
如何在单击子项时停止对父项的事件触发?
我想知道的可能解决方案:
CSS?
单击子项时,将 pointer-events : none
class 添加到父项。但是,这意味着稍后需要清除父级 pointer-events
class。
使用参考?
记录父 React
元素的 ref
,然后单击子元素,将 event.target
与 ref?我不喜欢这个,因为我不喜欢全局 ref
。
想法和更好的解决方案将不胜感激。问题是:
单击子项时如何停止父项上的事件触发器?
您可以使用 stopPropagation
stopPropagation
- Prevents further propagation of the current event in
the bubbling phase
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>
我想在 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">×</span>
</button>
<span className="label-text fs-12">
{ displayLabel }
</span>
</span>
);
}
}
export default LabelCancelable;
另一种解决方案是将以下内容附加到父级的事件回调:
if(event.target == event.currentTarget){
event.stopPropagation()
....
}
通过这种方式,您可以拦截源自附加的 DOM 节点的事件,而不相关的事件将转发到下一个节点。
我在 React 中遇到了同样的问题,并使用以下解决方案解决了它:
if(e.currentTarget != e.target ) return;
.......
我在使用 Material-UI DataGrid 时遇到了这个问题,并使用以下方法解决了它:
event.defaultMuiPrevented = true;
例如:
<DataGrid
onCellDoubleClick={(params, event) => {
if (!event.ctrlKey) {
event.defaultMuiPrevented = true;
}
}}
{...data}
/>
我发现这个解决方案最干净。谢谢@JohnFash!
onClick={(event) => event.currentTarget == event.target && doSomething(event)}
这里尝试更详细地解释这一点:
当你的鼠标进入父元素时,currentTarget被设置(事件),然后当它进入子元素时,目标发生变化。如果不检查,父级的onClick会触发,因为mouseleave事件没有触发。
我遇到过这种情况,当单击父元素时,它会翻转以显示具有不同颜色的子元素。不幸的是,当用户点击其中一种颜色时,父级上的 'click' 事件也会被触发。
如何在单击子项时停止对父项的事件触发?
我想知道的可能解决方案:
CSS?
单击子项时,将pointer-events : none
class 添加到父项。但是,这意味着稍后需要清除父级pointer-events
class。使用参考?
记录父React
元素的ref
,然后单击子元素,将event.target
与 ref?我不喜欢这个,因为我不喜欢全局ref
。
想法和更好的解决方案将不胜感激。问题是: 单击子项时如何停止父项上的事件触发器?
您可以使用 stopPropagation
stopPropagation
- Prevents further propagation of the current event in the bubbling phase
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>
我想在 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">×</span>
</button>
<span className="label-text fs-12">
{ displayLabel }
</span>
</span>
);
}
}
export default LabelCancelable;
另一种解决方案是将以下内容附加到父级的事件回调:
if(event.target == event.currentTarget){
event.stopPropagation()
....
}
通过这种方式,您可以拦截源自附加的 DOM 节点的事件,而不相关的事件将转发到下一个节点。
我在 React 中遇到了同样的问题,并使用以下解决方案解决了它:
if(e.currentTarget != e.target ) return;
.......
我在使用 Material-UI DataGrid 时遇到了这个问题,并使用以下方法解决了它:
event.defaultMuiPrevented = true;
例如:
<DataGrid
onCellDoubleClick={(params, event) => {
if (!event.ctrlKey) {
event.defaultMuiPrevented = true;
}
}}
{...data}
/>
我发现这个解决方案最干净。谢谢@JohnFash!
onClick={(event) => event.currentTarget == event.target && doSomething(event)}
这里尝试更详细地解释这一点: 当你的鼠标进入父元素时,currentTarget被设置(事件),然后当它进入子元素时,目标发生变化。如果不检查,父级的onClick会触发,因为mouseleave事件没有触发。