구성 요소 외부에 있는 클릭 이벤트를 수신하는 방법
드롭다운 컴포넌트 외부에서 클릭이 발생하면 드롭다운메뉴를 닫고 싶다.
그걸 어떻게 하는 거죠?
수명 주기 방법을 사용하여 문서에 이벤트 수신기를 추가하거나 제거합니다.
React.createClass({
handleClick: function (e) {
if (this.getDOMNode().contains(e.target)) {
return;
}
},
componentWillMount: function () {
document.addEventListener('click', this.handleClick, false);
},
componentWillUnmount: function () {
document.removeEventListener('click', this.handleClick, false);
}
});
이 컴포넌트의 48-54 행을 확인합니다.https://github.com/i-like-robots/react-tube-tracker/blob/91dc0129a1f6077bef57ea4ad9a860be0c600e9d/app/component/tube-tracker.jsx#L48-54
에 the가추 in in in를 했습니다.mousedown
★★★★★★★★★★★★★★★★★」mouseup
음음음같 뭇매하다
onMouseDown={this.props.onMouseDown} onMouseUp={this.props.onMouseUp}
그 후 부모에게 이렇게 합니다.
componentDidMount: function () {
window.addEventListener('mousedown', this.pageClick, false);
},
pageClick: function (e) {
if (this.mouseIsDownOnCalendar) {
return;
}
this.setState({
showCal: false
});
},
mouseDownHandler: function () {
this.mouseIsDownOnCalendar = true;
},
mouseUpHandler: function () {
this.mouseIsDownOnCalendar = false;
}
showCal
부울값입니다.true
내 경우에는 달력을 보여주고false
깁니니다
이벤트 대상을 확인합니다. 이벤트가 해당 컴포넌트 또는 해당 컴포넌트의 자식에 직접 있는 경우 클릭은 내부에 있습니다.그렇지 않으면 밖에 있었어요.
React.createClass({
clickDocument: function(e) {
var component = React.findDOMNode(this.refs.component);
if (e.target == component || $(component).has(e.target).length) {
// Inside of the component.
} else {
// Outside of the component.
}
},
componentDidMount: function() {
$(document).bind('click', this.clickDocument);
},
componentWillUnmount: function() {
$(document).unbind('click', this.clickDocument);
},
render: function() {
return (
<div ref='component'>
...
</div>
)
}
});
많은 컴포넌트에서 사용하는 경우에는 믹스인을 사용하는 것이 좋습니다.
var ClickMixin = {
_clickDocument: function (e) {
var component = React.findDOMNode(this.refs.component);
if (e.target == component || $(component).has(e.target).length) {
this.clickInside(e);
} else {
this.clickOutside(e);
}
},
componentDidMount: function () {
$(document).bind('click', this._clickDocument);
},
componentWillUnmount: function () {
$(document).unbind('click', this._clickDocument);
},
}
다음 예시를 참조하십시오.https://jsfiddle.net/0Lshs7mg/1/
특정 사용 사례에 대해 현재 받아들여지고 있는 답변은 다소 과대 설계되어 있습니다.했을 때 수 하려면 , 「기다리다」를 합니다.<select>
, 모 component an an an an an an an an an an an an an an an 를 붙입니다.onBlur
들러입입니니다
한다는 것입니다( 않을 수도 ).tab
또한 핵심 요소는 초점을 맞추고 요소를 흐리게 합니다. 그러나 이러한 단점은 더 복잡한 사용 사례에 대한 제한일 뿐이며, 이 경우 더 복잡한 솔루션이 필요할 수 있습니다.
var Dropdown = React.createClass({
handleBlur: function(e) {
// do something when user clicks outside of this element
},
render: function() {
return (
<select onBlur={this.handleBlur}>
...
</select>
);
}
});
컴포넌트 외부에서 발생하는 이벤트의 범용 이벤트 핸들러 react-outside-event를 작성했습니다.
구현 자체는 간단합니다.
- 에됩니다.
window
★★★★★★ 。 - 이벤트가 발생하면 구성 요소는 이벤트가 구성 요소 내에서 발생하는지 확인합니다.않으면 .
onOutsideEvent
대상 컴포넌트에 있습니다. - 컴포넌트가 마운트 해제되면 이벤트핸들러가 디액트 됩니다
import React from 'react';
import ReactDOM from 'react-dom';
/**
* @param {ReactClass} Target The component that defines `onOutsideEvent` handler.
* @param {String[]} supportedEvents A list of valid DOM event names. Default: ['mousedown'].
* @return {ReactClass}
*/
export default (Target, supportedEvents = ['mousedown']) => {
return class ReactOutsideEvent extends React.Component {
componentDidMount = () => {
if (!this.refs.target.onOutsideEvent) {
throw new Error('Component does not defined "onOutsideEvent" method.');
}
supportedEvents.forEach((eventName) => {
window.addEventListener(eventName, this.handleEvent, false);
});
};
componentWillUnmount = () => {
supportedEvents.forEach((eventName) => {
window.removeEventListener(eventName, this.handleEvent, false);
});
};
handleEvent = (event) => {
let target,
targetElement,
isInside,
isOutside;
target = this.refs.target;
targetElement = ReactDOM.findDOMNode(target);
isInside = targetElement.contains(event.target) || targetElement === event.target;
isOutside = !isInside;
if (isOutside) {
target.onOutsideEvent(event);
}
};
render() {
return <Target ref='target' {... this.props} />;
}
}
};
구성 요소를 사용하려면 상위 구성 요소를 사용하여 대상 구성 요소 클래스 선언을 래핑하고 처리할 이벤트를 정의해야 합니다.
import React from 'react';
import ReactDOM from 'react-dom';
import ReactOutsideEvent from 'react-outside-event';
class Player extends React.Component {
onOutsideEvent = (event) => {
if (event.type === 'mousedown') {
} else if (event.type === 'mouseup') {
}
}
render () {
return <div>Hello, World!</div>;
}
}
export default ReactOutsideEvent(Player, ['mousedown', 'mouseup']);
나에게 효과가 없었지만, 나는 그 답 중 하나를 투표로 뽑았다.그것은 결국 나를 이 해결책으로 이끌었다.저는 작업 순서를 조금 바꿨습니다.타겟에서는 mouseDown을, 타겟에서는 mouseUp을 듣습니다.둘 중 하나가 TRUE로 반환되면 모드를 닫지 않습니다.클릭이 등록되면 어디서든 두 개의 부울 {mouseDownOnModal, mouseUpOnModal}이(가) false로 다시 설정됩니다.
componentDidMount() {
document.addEventListener('click', this._handlePageClick);
},
componentWillUnmount() {
document.removeEventListener('click', this._handlePageClick);
},
_handlePageClick(e) {
var wasDown = this.mouseDownOnModal;
var wasUp = this.mouseUpOnModal;
this.mouseDownOnModal = false;
this.mouseUpOnModal = false;
if (!wasDown && !wasUp)
this.close();
},
_handleMouseDown() {
this.mouseDownOnModal = true;
},
_handleMouseUp() {
this.mouseUpOnModal = true;
},
render() {
return (
<Modal onMouseDown={this._handleMouseDown} >
onMouseUp={this._handleMouseUp}
{/* other_content_here */}
</Modal>
);
}
이것은 모든 코드가 부모 컴포넌트가 아닌 자식 컴포넌트에 있다는 장점이 있습니다.즉, 이 부품을 재사용할 때 복사할 보일러 플레이트 코드가 없습니다.
- 화면 전체에 걸쳐 고정 레이어를 작성합니다(
.backdrop
). - 대상 요소(
.target
)의 외부.backdrop
스태킹 인덱스가 높은 요소(z-index
).
그런 다음 을 클릭합니다..backdrop
요소는 '의 요소'로 간주됩니다..target
요소"를 선택합니다.
.click-overlay {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 1;
}
.target {
position: relative;
z-index: 2;
}
- 다음은 예를 제시하겠습니다.http://jsfiddle.net/LHmwd/
- 자세한 것은, https://github.com/facebook/react/issues/579 를 참조해 주세요.
사용할 수 있습니다.ref
이를 실현하기 위해서는 다음과 같은 것이 필요합니다.
를 추가합니다.ref
구성 요소:
<div ref={(element) => { this.myElement = element; }}></div>
그런 다음 다음과 같이 요소 외부의 클릭을 처리하는 기능을 추가할 수 있습니다.
handleClickOutside(e) {
if (!this.myElement.contains(e)) {
this.setState({ myElementVisibility: false });
}
}
마지막으로 에서 이벤트청취자를 추가 및 삭제하면 마운트되고 마운트 해제됩니다.
componentWillMount() {
document.addEventListener('click', this.handleClickOutside, false); // assuming that you already did .bind(this) in constructor
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside, false); // assuming that you already did .bind(this) in constructor
}
파티는 매우 늦었지만 드롭다운의 부모 요소에 관련 코드로 블러 이벤트를 설정하고 드롭다운이 열려 있는지 여부를 확인하는 부모 요소에 머드다운 리스너를 부착하는 데 성공했습니다.또한 이벤트 전파가 열려 있으면 이벤트 전파를 중지하여 흐림 이벤트가 트리거되지 않도록 합니다.
잔털 깎기 이벤트가 거품이 끼기 때문에 자녀에 대한 잔털 깎기가 부모에게 흐릿함을 주는 것을 방지할 수 있습니다.
/* Some react component */
...
showFoo = () => this.setState({ showFoo: true });
hideFoo = () => this.setState({ showFoo: false });
clicked = e => {
if (!this.state.showFoo) {
this.showFoo();
return;
}
e.preventDefault()
e.stopPropagation()
}
render() {
return (
<div
onFocus={this.showFoo}
onBlur={this.hideFoo}
onMouseDown={this.clicked}
>
{this.state.showFoo ? <FooComponent /> : null}
</div>
)
}
...
e.provent Default()는 가능한 한 호출할 필요가 없습니다만, 파이어폭스는 어떠한 이유로든 파이어폭스 없이는 동작하지 않습니다.Chrome, Firefox 및 Safari에서 작동합니다.
나는 이것에 대해 더 간단한 방법을 찾았다.
추가만 하면 됩니다.onHide(this.closeFunction)
모달로
<Modal onHide={this.closeFunction}>
...
</Modal>
모달 닫는 기능이 있다고 가정합니다.
뛰어난 리액트 온클릭 아웃사이드 믹스인을 사용합니다.
npm install --save react-onclickoutside
그리고 나서.
var Component = React.createClass({
mixins: [
require('react-onclickoutside')
],
handleClickOutside: function(evt) {
// ...handling code goes here...
}
});
언급URL : https://stackoverflow.com/questions/23821768/how-to-listen-for-click-events-that-are-outside-of-a-component
'source' 카테고리의 다른 글
메서드 POST에 대한 Wordpress REST API 사용자 지정 끝점 (0) | 2023.03.28 |
---|---|
MongoDB에서 프라이머리 키를 설정하는 방법 (0) | 2023.03.28 |
jeast spy인덱스 파일에서 작동하지 않으므로 속성을 재정의할 수 없습니다. (0) | 2023.03.28 |
React Native 투명 오버레이 (0) | 2023.03.28 |
Redux, 데이터에 액세스하려면 모든 컨테이너에 있는 스토어를 가져와야 합니까? (0) | 2023.03.28 |