我试图在ReactJS组件中使用event.stopPropagation()来阻止单击事件冒泡并触发遗留代码中与JQuery关联的click事件,但是似乎React的stopPropagation()只能停止传播到事件也附加在React中,并且JQuery的stopPropagation()不会停止传播到随React附加的事件。
有什么方法可以使stopPropagation()在这些事件中起作用?我编写了一个简单的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(); }); });
React使用事件委派和单个事件侦听器来启动document冒泡的事件,如本例中的“ click”,这意味着无法停止传播;当您在React中与真实事件互动时,真实事件已经传播了。stopPropagation由于React在内部处理合成事件的传播,因此可以对React的合成事件进行处理。
document
stopPropagation
使用Event.stopImmediatePropagation以防止你的其他(jQuery的在这种情况下)听众根被调用。IE9 +和现代浏览器都支持它。
Event.stopImmediatePropagation
stopPropagation: function(e){ e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); },
您的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。