Estoy tratando de usar event.stopPropagation () dentro de un componente ReactJS para evitar que un evento click aumente y active un evento click que se adjuntó con JQuery en el código heredado, pero parece que stopPropagation () de React solo detiene la propagación a eventos también adjunto en React, y stopPropagation () de JQuery no detiene la propagación a eventos adjuntos con React.
¿Hay alguna manera de hacer que stopPropagation () funcione en estos eventos? Escribí un JSFiddle simple para demostrar estos comportamientos:
/** @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();
});
});
javascript
jquery
reactjs
lofiinterstate
fuente
fuente
event.nativeEvent.stopImmediatePropagation
para evitar que se activen otros escuchas de eventos, pero no se garantiza el orden de ejecución.stopImmediatePropagation
oyentes de eventos de reclamos serán llamados en el orden en que fueron vinculados. Si su React JS se inicializa antes de su jQuery (como está en su violín), la detención de la propagación inmediata funcionará.componentDidMount
, pero podría interferir con otros controladores de eventos React de maneras inesperadas..stop-propagation
necesariamente funcionará. Su ejemplo utiliza la delegación de eventos pero está intentando detener la propagación en el elemento. El oyente tiene que ser unido al elemento en sí:$('.stop-propagation').on('click', function(e) { e.stopPropagation(); });
. Este violín evita toda propagación como lo estaba intentando: jsfiddle.net/7LEDT/6Respuestas:
React utiliza la delegación de eventos con un único detector de eventos activado
document
para eventos que burbujean, como 'hacer clic' en este ejemplo, lo que significa que no es posible detener la propagación; el evento real ya se ha propagado cuando interactúas con él en React.stopPropagation
El evento sintético de React es posible porque React maneja la propagación de eventos sintéticos internamente.Trabajando JSFiddle con las correcciones desde abajo.
Reaccionar Detener propagación en el evento jQuery
Utilícelo
Event.stopImmediatePropagation
para evitar que se llame a sus otros oyentes (jQuery en este caso) en la raíz. Es compatible con IE9 + y navegadores modernos.jQuery Stop Propagation on React Event
Su código jQuery también usa la delegación de eventos, lo que significa que llamar
stopPropagation
al controlador no detiene nada; el evento ya se ha propagadodocument
y se activará el oyente de React.Para evitar la propagación más allá del elemento, el oyente debe estar vinculado al elemento mismo:
Editar (14/01/2016): se aclaró que la delegación solo se usa necesariamente para eventos que burbujean. Para obtener más detalles sobre el manejo de eventos, la fuente de React tiene comentarios descriptivos: ReactBrowserEventEmitter.js .
fuente
document
o el componente React raíz? La página vinculada solo dice "en el nivel superior", lo que considero que no es eldocument
(pero no puedo entender si esto es relevante).window
lugar dedocument
: stackoverflow.com/a/52879137/438273Vale la pena señalar (de este problema ) que si está adjuntando eventos
document
,e.stopPropagation()
no va a ayudar. Como solución alternativa, puede usar enwindow.addEventListener()
lugar dedocument.addEventListener
, luegoevent.stopPropagation()
detendrá la propagación del evento a la ventana.fuente
Todavía es un momento interesante:
Use esta construcción, si su función está envuelta por etiqueta
fuente
event.nativeEvent
es la respuesta correcta Pude usarlocomposedPath()
:event.nativeEvent.composedPath()
wrapped by tag
? ¿podría por favor dar un ejemplo?<div onClick=(firstHandler)> <div onClick=(secHandler)>active text</div> </div>
Pude resolver esto agregando lo siguiente a mi componente:
fuente
Ayer me encontré con este problema, así que creé una solución amigable con React.
Echa un vistazo a react-native-listener . Funciona muy bien hasta ahora. Comentarios apreciados.
fuente
react-native-listener
usosfindDomNode
que serán obsoletos github.com/yannickcr/eslint-plugin-react/issues/…De la documentación de React : los controladores de eventos a continuación se activan por un evento en la fase de propagación . Para registrar un controlador de eventos para la fase de captura, agregue Captura . (énfasis añadido)
Si tiene un detector de eventos de clic en su código React y no desea que brote, creo que lo que quiere hacer es usarlo en
onClickCapture
lugar deonClick
. Luego, pasaría el evento al controlador y lo haríaevent.nativeEvent.stopPropagation()
para evitar que el evento nativo se propague a un oyente de eventos JS (o cualquier cosa que no reaccione).fuente
Actualización: ahora puedes
<Elem onClick={ proxy => proxy.stopPropagation() } />
fuente
Se está utilizando una solución rápida en
window.addEventListener
lugar dedocument.addEventListener
.fuente