ReactJS SyntheticEvent stopPropagation() 仅适用于 React 事件吗? [英] ReactJS SyntheticEvent stopPropagation() only works with React events?

查看:29
本文介绍了ReactJS SyntheticEvent stopPropagation() 仅适用于 React 事件吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 ReactJS 组件中使用 event.stopPropagation() 来阻止点击事件冒泡并触发在遗留代码中与 JQuery 附加的点击事件,但似乎 React 的 stopPropagation() 只会停止传播到 React 中也附加的事件,而 JQuery 的 stopPropagation() 不会停止传播到 React 附加的事件.

有什么方法可以让 stopPropagation() 在这些事件中工作吗?我写了一个简单的 JSFiddle 来演示这些行为:

/** @jsx React.DOM */var 传播 = React.createClass({警报:功能(){alert('反应警报');},停止传播:函数(e){e.stopPropagation();},渲染:函数(){返回 (<div><div onClick={this.alert}><a href="#" onClick={this.stopPropagation}>React 在 React 事件上停止传播</a>

<div className="警报"><a href="#" onClick={this.stopPropagation}>React 停止传播 JQuery 事件</a>

<div onClick={this.alert}><a href="#" className="stop-propagation">JQuery 在 React 事件上停止传播</a>

<div className="警报"><a href="#" className="stop-propagation">JQuery 在 JQuery 事件上停止传播</a>

);}});React.renderComponent(<Propagation/>, document.body);$(函数(){$(document).on('click', '.alert', function(e){alert('Jquery 警报');});$(document).on('click', '.stop-propagation', function(e){e.stopPropagation();});});

解决方案

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

使用下面的修复JSFiddle.

在 jQuery 事件上响应停止传播

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

stopPropagation: function(e){e.stopPropagation();e.nativeEvent.stopImmediatePropagation();},

jQuery 在 React 事件上停止传播

您的 jQuery 代码也使用事件委托,这意味着在处理程序中调用 stopPropagation 不会停止任何事情;事件已经传播到document,React的监听器会被触发.

//监听器绑定到`document`,事件委托$(document).on('click', '.stop-propagation', function(e){e.stopPropagation();});

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

//监听器绑定到`.stop-propagation`,没有委托$('.stop-propagation').on('click', function(e){e.stopPropagation();});

编辑 (2016/01/14): 阐明委托必须仅用于冒泡的事件.有关事件处理的更多详细信息,React 的源代码具有描述性注释:ReactBrowserEventEmitter.js.

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

jQuery Stop Propagation on React Event

Your jQuery code uses event delegation as well, which means calling stopPropagation in the handler is not stopping anything; the event has already propagated to document, and React's listener will be triggered.

// 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): Clarified that delegation is necessarily only used for events that bubble. For more details on event handling, React's source has descriptive comments: ReactBrowserEventEmitter.js.

这篇关于ReactJS SyntheticEvent stopPropagation() 仅适用于 React 事件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆