Я пытаюсь использовать event.stopPropagation () в компоненте ReactJS, чтобы остановить событие щелчка от всплытия и запуска события щелчка, которое было прикреплено с JQuery в устаревшем коде, но похоже, что stopPropagation () React только останавливает распространение на события также прикреплен к React, а stopPropagation () JQuery не останавливает распространение событий, связанных с 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();
});
});
javascript
jquery
reactjs
lofiinterstate
источник
источник
event.nativeEvent.stopImmediatePropagation
чтобы предотвратить запуск других прослушивателей событий, но порядок выполнения не гарантируется.stopImmediatePropagation
прослушиватели событий утверждений будут вызываться в том порядке, в котором они были связаны. Если ваш React JS инициализирован до вашего jQuery (как в вашей скрипке), сработает остановка немедленного распространения.componentDidMount
, но он может неожиданным образом мешать работе других обработчиков событий React..stop-propagation
обязательно не сработает. В вашем примере используется делегирование событий, но выполняется попытка остановить распространение элемента. Слушатель должен быть привязан к самому элементу:$('.stop-propagation').on('click', function(e) { e.stopPropagation(); });
. Эта скрипка предотвращает любое распространение, как вы пытались: jsfiddle.net/7LEDT/6Ответы:
React использует делегирование событий с одним включенным прослушивателем
document
событий для событий, которые всплывают, например «щелчок» в этом примере, что означает, что остановить распространение невозможно; реальное событие уже распространено к тому моменту, когда вы взаимодействуете с ним в React.stopPropagation
на синтетическом событии React возможно, потому что React обрабатывает распространение синтетических событий внутри себя.Рабочий JSFiddle с исправлениями снизу.
React Stop Propagation on jQuery Event
Используйте,
Event.stopImmediatePropagation
чтобы предотвратить вызов других ваших слушателей (в данном случае jQuery) в корневом каталоге. Он поддерживается в IE9 + и современных браузерах.jQuery Остановить распространение при событии React
В вашем коде jQuery также используется делегирование событий, что означает, что вызов
stopPropagation
обработчика ничего не останавливает; событие уже переданоdocument
, и будет запущен слушатель React.Чтобы предотвратить распространение за пределы элемента, слушатель должен быть привязан к самому элементу:
Изменить (2016/01/14): Уточнено, что делегирование обязательно используется только для событий, которые всплывают. Для получения дополнительной информации об обработке событий в источнике React есть описательные комментарии: ReactBrowserEventEmitter.js .
источник
document
или корневой компонент React? На связанной странице просто написано «на верхнем уровне», что, как я понимаю, означает, что это не тотdocument
(но я не могу понять, актуально ли это вообще).window
вместоdocument
: stackoverflow.com/a/52879137/438273Стоит отметить (из этой проблемы ), что если вы прикрепляете события к
document
,e.stopPropagation()
это не поможет. В качестве обходного пути вы можете использоватьwindow.addEventListener()
вместоdocument.addEventListener
, тогдаevent.stopPropagation()
событие не будет распространяться в окно.источник
Это все еще один интересный момент:
Используйте эту конструкцию, если ваша функция обернута тегом
источник
event.nativeEvent
правильный ответ; Я смог использоватьcomposedPath()
через это:event.nativeEvent.composedPath()
wrapped by tag
? не могли бы вы привести пример?<div onClick=(firstHandler)> <div onClick=(secHandler)>active text</div> </div>
Я смог решить эту проблему, добавив в свой компонент следующее:
источник
Вчера я столкнулся с этой проблемой, поэтому создал удобное для React решение.
Проверьте response-native-listener . Пока он работает очень хорошо. Обратная связь приветствуется.
источник
react-native-listener
использование,findDomNode
которое будет устаревшим github.com/yannickcr/eslint-plugin-react/issues/…Из документации React : Обработчики событий ниже запускаются событием в фазе восходящей цепочки . Чтобы зарегистрировать обработчик событий для фазы захвата, добавьте Capture . (курсив мой)
Если у вас есть прослушиватель событий щелчка в вашем коде React, и вы не хотите, чтобы он всплывал, я думаю, что вы хотите использовать
onClickCapture
вместоonClick
. Затем вы передадите событие обработчику и сделаете так,event.nativeEvent.stopPropagation()
чтобы нативное событие не всплывало до ванильного прослушивателя событий JS (или чего-либо, что не реагирует).источник
Обновление: теперь вы можете
<Elem onClick={ proxy => proxy.stopPropagation() } />
источник
Быстрый обходной путь - использование
window.addEventListener
вместоdocument.addEventListener
.источник