ReactJS SyntheticEvent stopPropagation()只适用于React事件
ReactJS SyntheticEvent stopPropagation() only works with React events?
我试图在一个ReactJS组件中使用event.stopPropagation()来阻止点击事件冒气泡并触发在遗留代码中附加的JQuery的点击事件,但似乎React的stopPropagation()只会停止传播到也附加在React中的事件,而JQuery的stopPropagation()不会停止传播到附加在React中的事件。
是否有办法使stopPropagation()跨这些事件工作?我编写了一个简单的jsf来演示这些行为:
/** @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();
});
});
对于冒泡事件,React在document
上使用带有单个事件侦听器的事件委托,例如本例中的'click',这意味着不可能停止传播;当你在React中与它交互时,真实的事件已经传播了。在React的合成事件上stopPropagation
是可能的,因为React内部处理合成事件的传播。
正在工作的JSFiddle从下面修复
React停止jQuery事件传播
使用Event.stopImmediatePropagation
来防止在根节点上的其他监听器(在本例中是jQuery)被调用。它支持IE9+和现代浏览器。
stopPropagation: function(e){
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
},
- 警告:监听器是按照它们被绑定的顺序调用的。React必须在其他代码(这里是jQuery)之前初始化才能正常工作。
jQuery Stop Propagation on React Event
你的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();
});
Edit (2016/01/14):澄清委派必须仅用于冒泡的事件。有关事件处理的更多细节,React的源代码有描述性注释:ReactBrowserEventEmitter.js.
这仍然是一个有趣的时刻:
ev.preventDefault()
ev.stopPropagation();
ev.nativeEvent.stopImmediatePropagation();
如果您的函数被标签
值得注意的是(从这个问题中),如果您将事件附加到document
, e.stopPropagation()
将不会有帮助。作为解决方法,您可以使用window.addEventListener()
而不是document.addEventListener
,然后event.stopPropagation()
将阻止事件传播到窗口。
来自React文档:下面的事件处理程序是由冒泡阶段中的事件触发的。要为捕获阶段注册一个事件处理程序,附加capture 。(强调)
如果你有一个点击事件监听器在你的React代码,你不希望它冒泡,我认为你要做的是使用onClickCapture
而不是onClick
。然后将事件传递给处理程序,并执行event.nativeEvent.stopPropagation()
以防止本机事件冒泡到普通JS事件侦听器(或任何未响应的事件)。
我可以通过向我的组件添加以下内容来解决这个问题:
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('click', (event) => {
event.stopPropagation();
}, false);
}
React 17将事件委托给root
而不是document
,这可能会解决问题。更多细节请点击这里。你也可以参考我的博客
我昨天遇到了这个问题,所以我创建了一个对react友好的解决方案。
查看react-native-listener。到目前为止,它运行得很好。反馈感激。
一个快速的解决方法是使用window.addEventListener
代替document.addEventListener
。
更新:<Elem onClick={ proxy => proxy.stopPropagation() } />
在我的情况下,e.stopPropagation()
没有工作,因为孩子有onChange
事件,父母onClick
。从另一个StackOverflow答案中获得见解
更改事件和点击事件是不同的事件。
Meagning:在onChange
内部调用e.stopPropagation()
不会阻止onClick
的触发。
解决方案有onChange或onClick。
我解决这个问题的方法是在回调时添加一个if语句,检查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)
}
- JQueryhide()不适用于Mozzilla,但适用于Chrome
- PHP中的setcookie仅适用于localhost
- html5 drawImage适用于firefox,而不是chrome
- 提供“;onClick"适用于iPad(触摸屏)和桌面用户的默认功能
- jQuery表单验证适用于Mozilla和Internet Explorer,但不适用于Chrome或Safari
- ResolveUrl是否适用于././也
- Firebase updateChildValues适用于IOS,但不适用于Web和Android
- JavaScript警报适用于int,但不适用于string
- SQLite插件适用于Mac和Windows,但不适用于手机上的Safari
- Regex Replace仅适用于Last Match
- window.onload适用于aspx页面,但不适用于普通html
- Jquery Ajax POST不工作.适用于GET
- 画布上的自定义字体仅适用于safari
- Javascript仅适用于alert()和Debug模式
- JS适用于Firefox和Safari,但不适用于Chrome.此处'是我的网站
- Regex不适用于Firefox,但适用于Chrome
- 通过单击主菜单外部关闭子菜单'不适用于IE,但适用于Firefox&铬
- AngularJS$http.post没有'不适用于Chrome,仅适用于IE
- Javascript仅适用于jQuery mobile中的页面刷新
- ReactJS SyntheticEvent stopPropagation()只适用于React事件