只对 ReactJS 合成事件停止传播()工作的 ReactJS 合成事件停止传播() ?

我正在尝试在 ReactJS 组件中使用 event.stop 繁殖()来阻止一个单击事件冒泡并触发一个在遗留代码中与 JQuery 连接的单击事件,但似乎 React 的 stop 繁殖()只能阻止对同样与 React 连接的事件的传播,而 JQuery 的 stop 繁殖()并不能阻止对与 React 连接的事件的传播。

有没有什么方法可以在这些事件之间使停止繁殖()工作?我写了一个简单的 JSFiddle来演示这些行为:

/** @jsx React.DOM */
var Propagation = React.createClass({
alert: function(){
alert('React Alert');
},
stopPropagation: function(e){
e.stopPropagation();
},
render: function(){
return (
<div>
<div onClick={this.alert}>
<a href="#" onClick={this.stopPropagation}>React Stop Propagation on React Event</a>
</div>
<div className="alert">
<a href="#" onClick={this.stopPropagation}>React Stop Propagation on JQuery Event</a>
</div>
<div onClick={this.alert}>
<a href="#" className="stop-propagation">JQuery Stop Propagation on React Event</a>
</div>
<div className="alert">
<a href="#" className="stop-propagation">JQuery Stop Propagation on JQuery Event</a>
</div>
</div>
);
}
});


React.renderComponent(<Propagation />, document.body);


$(function(){
$(document).on('click', '.alert', function(e){
alert('Jquery Alert');
});


$(document).on('click', '.stop-propagation', function(e){
e.stopPropagation();
});
});
156130 次浏览

React 使用 document上带有单个事件监听器的事件委托来处理冒泡的事件,比如本例中的“ click”,这意味着不可能停止传播; 在 React 中,当您与真实事件交互时,它已经传播了。在 React 的合成事件上 stopPropagation是可能的,因为 React 在内部处理合成事件的传播。

使用下面的修复程序工作 JSFiddle

JQuery 事件上的反应停止传播

使用 Event.stopImmediatePropagation可以防止调用根目录上的其他侦听器(本例中为 jQuery)。IE9 + 和现代浏览器都支持它。

stopPropagation: function(e){
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
},
  • 注意: 调用侦听器的顺序是它们被绑定的顺序。React 必须在其他代码(这里是 jQuery)之前初始化,这样才能正常工作。

反应事件的 jQuery 停止传播

JQuery 代码也使用事件委托,这意味着在处理程序中调用 stopPropagation不会停止任何操作; 事件已经传播到 document,React 的侦听器将被触发。

// Listener bound to `document`, event delegation
$(document).on('click', '.stop-propagation', function(e){
e.stopPropagation();
});

要防止超出元素的传播,侦听器必须绑定到元素本身:

// Listener bound to `.stop-propagation`, no delegation
$('.stop-propagation').on('click', function(e){
e.stopPropagation();
});

编辑(2016/01/14) : 澄清授权必须只用于泡沫事件。关于事件处理的更多细节,React 的源代码有描述性的注释: ReactBrowserEventEmitter.js

我昨天碰到了这个问题,所以我创建了一个反应友好的解决方案。

看看 反应-本地-听众。到目前为止工作得很好。感谢你的反馈。

我可以通过在组件中添加以下内容来解决这个问题:

componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('click', (event) => {
event.stopPropagation();
}, false);
}

更新: 您现在可以 <Elem onClick={ proxy => proxy.stopPropagation() } />

这仍是一个有趣的时刻:

ev.preventDefault()
ev.stopPropagation();
ev.nativeEvent.stopImmediatePropagation();

如果函数由标记包装,则使用此构造

值得注意的是(来自 这个问题) ,如果您将事件附加到 documente.stopPropagation()不会有帮助。作为解决方案,您可以使用 window.addEventListener()而不是 document.addEventListener,然后 event.stopPropagation()将停止事件传播到窗口。

来自 反应文件: 下面的事件处理程序是由事件 在冒泡阶段处理的 触发了。要为捕获阶段注册事件处理程序,请使用 附加捕获。(加重语气)

如果你有一个点击事件侦听器在你的反应代码,你不希望它冒泡,我认为你要做的是使用 onClickCapture而不是 onClick。然后将事件传递给处理程序,并执行 event.nativeEvent.stopPropagation()以防止本机事件冒泡到普通的 JS 事件侦听器(或任何没有反应的事件)。

一个快速的解决方案是使用 window.addEventListener而不是 document.addEventListener

将17个事件委托给 root而不是 document,这可能会解决问题。 更多细节 给你。 你也可以参考 我的博客

在我的案例中,e.stopPropagation()不起作用,因为孩子有 onChange事件,父母 onClick

更改和单击事件是不同的事件。

意思是: 在 onChange内部调用 e.stopPropagation()不会阻止触发 onClick

同时使用 onChange 或 onClick 的解决方案。

我解决这个问题的方法是在回调函数中添加一个 如果语句来检查 event.target,如果它与我期望的元素不同,那么就从函数返回

// Callback from my own app
function exitResultsScreen(event){
// Check element by ID
if (event.target.className !== sass.div__search_screen){return}
        

// Executed only when the right elements calls
setShowResults(false)
}