ReactJSコンポーネント内でevent.stopPropagation()を使用して、クリックイベントがバブリングするのを停止し、レガシーコードのJQueryでアタッチされたクリックイベントをトリガーしようとしていますが、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
の単一のイベントリスナーでイベント委任を使用します。つまり、伝播を停止することはできません。実際のイベントは、Reactでイベントと対話するまでに既に伝播しています。 Reactは内部的に合成イベントの伝播を処理するため、Reactの合成イベントのstopPropagation
は可能です。
ルート上の他の(この場合はjQuery)リスナーが呼び出されないようにするには、 Event.stopImmediatePropagation
を使用します。 IE9 +および最新のブラウザーでサポートされています。
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のソースに説明的なコメントがあります。 https://github.com/facebook/react/blob/b87aabd/packages/react-dom/src/events/ReactBrowserEventEmitter.js#L52-L85
昨日この問題に遭遇したので、Reactに優しいソリューションを作成しました。
react-native-listener を確認してください。これまでのところ非常にうまく機能しています。フィードバックに感謝します。
コンポーネントに次を追加することでこれを解決できました。
componentDidMount() {
ReactDOM.findDOMNode(this).addEventListener('click', (event) => {
event.stopPropagation();
}, false);
}
まだ興味深い1つの瞬間です。
ev.preventDefault()
ev.stopPropagation();
ev.nativeEvent.stopImmediatePropagation();
関数がタグでラップされている場合、この構造を使用します
( この問題 から)document
にイベントをアタッチしている場合、e.stopPropagation()
は役に立たないことに注意してください。回避策として、document.addEventListener
の代わりにwindow.addEventListener()
を使用できます。その後、event.stopPropagation()
は、イベントがウィンドウに伝播するのを停止します。
更新:<Elem onClick={ proxy => proxy.stopPropagation() } />
ができるようになりました