ReactJS SyntheticEvent stopPropagation()仅适用于React事件?

时间:2014-06-25 18:10:10

标签: javascript jquery reactjs

我试图在ReactJS组件中使用event.stopPropagation()来阻止点击事件冒泡并触发遗留代码中使用JQuery附加的点击事件,但似乎是React' s stopPropagation()仅停止传播到React中附加的事件,而JQuery的stopPropagation()不会停止传播到React附带的事件。

有没有办法让stopPropagation()在这些事件中发挥作用?我写了一个简单的JSFiddle来演示这些行为:

http://jsfiddle.net/7LEDT/3/

/** @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();
    });
});

9 个答案:

答案 0 :(得分:138)

React将事件委托与document上的单个事件监听器一起用于冒泡的事件,如本示例中的“click”,这意味着无法停止传播;当你在React中与它交互时,真实事件已经传播了。关于React的合成事件的stopPropagation是可能的,因为React在内部处理合成事件的传播。

使用下面的修复工具JSFiddle:http://jsfiddle.net/7LEDT/6/

在jQuery事件上反应停止传播

使用Event.stopImmediatePropagation来阻止调用root上的其他(在本例中为jQuery)侦听器。 IE9 +和现代浏览器都支持它。

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
},
  • 警告:监听器按照绑定的顺序进行调用。必须在其他代码(这里是jQuery)之前初始化React才能使其正常工作。

jQuery在React事件上的停止传播

你的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的源代码具有描述性注释:https://github.com/facebook/react/blob/b87aabd/packages/react-dom/src/events/ReactBrowserEventEmitter.js#L52-L85

答案 1 :(得分:6)

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

结帐react-native-listener。到目前为止,它运作良好。反馈意见。

答案 2 :(得分:6)

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

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

答案 3 :(得分:4)

这仍然是一个有趣的时刻:

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

如果您的函数由标记

包装,请使用此结构

答案 4 :(得分:4)

值得一提的是(来自this issue),如果您将事件附加到documente.stopPropagation()将无济于事。解决方法是,您可以使用window.addEventListener()而不是document.addEventListener,然后event.stopPropagation()将阻止事件传播到窗口。

答案 5 :(得分:3)

第17号反应将事件委托给root而不是document,这可能会解决问题。 更多详细信息here

答案 6 :(得分:1)

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

答案 7 :(得分:1)

React documentation: 下面的事件处理程序在冒泡阶段被事件触发。要为捕获阶段注册事件处理程序,请附加捕获。 (强调)

如果您的React代码中有一个click事件监听器,并且您不想让它冒泡,我想您想做的就是使用onClickCapture而不是onClick。然后,您将事件传递给处理程序,并进行event.nativeEvent.stopPropagation()来防止本机事件冒泡到普通JS事件侦听器(或任何不响应的事件)。

答案 8 :(得分:1)

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

相关问题