I'm trying to use event.stopPropagation() within a ReactJS component to stop a click event from bubbling up and triggering a click event that was attached with JQuery in legacy code, but it seems like React's stopPropagation() only stops propagation to events also attached in React, and JQuery's stopPropagation() doesn't stop propagation to events attached with React.

Is there any way to make stopPropagation() work across these events? I wrote a simple JSFiddle to demonstrate these behaviors:

/** @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 uses event delegation with a single event listener on document for events that bubble, like 'click' in this example, which means stopping propagation is not possible; the real event has already propagated by the time you interact with it in React. stopPropagation on React's synthetic event is possible because React handles propagation of synthetic events internally.

Working JSFiddle with the fixes from below.

React Stop Propagation on jQuery Event

Use Event.stopImmediatePropagation to prevent your other (jQuery in this case) listeners on the root from being called. It is supported in IE9+ and modern browsers.

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
},
  • Caveat: Listeners are called in the order in which they are bound. React must be initialized before other code (jQuery here) for this to work.

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

To prevent propagation beyond the element, the listener must be bound to the element itself:

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

Edit (2016/01/14):澄清了授权仅适用于存在泡沫的事件.有关事件处理的更多详细信息,React的来源有描述性注释:ReactBrowserEventEmitter.js.

Jquery相关问答推荐

JQuery AJAX 成功事件未触发

在函数 jQuery 中更改语言

如何使用 jQuery 的 drop 事件上传从桌面拖动的文件?

$(document).ready(function() VS $(function(){

在 jQuery 事件中控制this的值

Bootstrap 3 RC 1 中的 typeahead JavaScript 模块在哪里?

jQuery - 获取 ajax POST 的表单值

如何使用 jQuery 获取 div 的当前类?

不使用插件的 jQuery 缓动函数

Rails,单击link_to helper后未加载javascript

动画元素变换旋转

将返回的 JSON 对象属性转换为(较低的第一个)camelCase

jQuery ajax (jsonp) 忽略超时并且不触发错误事件

Bootstrap 折叠动画不流畅

Javascript 将 Markdown/Textile 转换为 HTML(理想情况下,返回 Markdown/Textile)

为什么要使用发布/订阅模式(在 JS/jQuery 中)?

使用javascript将HTML页面中的div下载为pdf

D3 和​​ jQuery 有什么区别?

如何使用 bootstrap 中的 selectpicker 插件在 Select 时设置选定值

使用 jQuery 将一个标签替换为另一个标签