我有一个事件监听器,可以监听点击。如果这些点击不在给定的dom元素之外,则将调用某个函数(在这种情况下为handleClick
)。
现在,仅当事件目标不是具有handleClick
引用的事件目标时,才调用函数this.setWrapper
。
我想知道如果我碰巧也点击了handleClick
,如何防止.boxTwo
被呼叫。
请注意,我不是要在.boxTwo
的div上添加引用,而是要查询DOM以标识在类名为'boxTwo'的div内发生的任何点击,而不是这样做。谢谢!
class App extends React.Component {
constructor() {
super();
this.state = {onClick: false};
this.setWrapperRef = this.setWrapperRef.bind(this);
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick);
}
setWrapperRef(node) {
this.wrapperRef = node;
}
handleClick(event) {
if (this.wrapperRef && !this.wrapperRef.contains(event.target)) {
this.setState({onClick: !this.state.onClick});
}
}
render() {
return (
<section>
<div className="boxOne" ref={this.setWrapperRef} />
<div className="boxTwo" />
<div>{this.state.onClick ? "On" : "Off"}</div>
</section>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
.boxOne {
height: 100px;
width: 100px;
background: pink;
}
.boxTwo {
margin: 30px;
height: 50px;
width: 70px;
border: solid black 2px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
答案 0 :(得分:1)
event.target.className
是否等于boxTwo
,就像下面的代码片段一样。boxOne
类,则可以使用相同的“技术”来防止调用函数。!event.target.className
多一点点,出于可读性考虑,我会以这种方式完成
handleClick(event) {
// The ones that don't trigger
const disabledTriggers = ['boxOne', 'boxTwo'];
// Ok if no class contained in our event classList are disabled
const ok = !disabledTriggers.some(c => event.target.classList && event.target.classList.contains(c))
if(ok) {
this.setState({onClick: !this.state.onClick});
}
}
这是解决方案和最少修改的片段。
class App extends React.Component {
constructor() {
super();
this.state = {onClick: false};
this.setWrapperRef = this.setWrapperRef.bind(this);
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick);
}
setWrapperRef(node) {
this.wrapperRef = node;
}
handleClick(event) {
if (event.target.className !== 'boxTwo' && this.wrapperRef && !this.wrapperRef.contains(event.target)) {
this.setState({onClick: !this.state.onClick});
}
}
render() {
return (
<section>
<div className="boxOne" ref={this.setWrapperRef} />
<div className="boxTwo" />
<div>{this.state.onClick ? "On" : "Off"}</div>
</section>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
.boxOne {
height: 100px;
width: 100px;
background: pink;
}
.boxTwo {
margin: 30px;
height: 50px;
width: 70px;
border: solid black 2px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
答案 1 :(得分:0)
让我解释一下我做了什么。
event.target.classList
(返回当前目标类的列表),并检查是否有来自classList的任何人到状态wrapperRefs。如果不存在,则在组件外部单击。我希望这 帮助您。
如果您有任何疑问,请在下面评论。我想为您提供尽可能多的帮助。
class App extends React.Component {
constructor() {
super();
this.state = {onClick: false, wrapperRefs: ['boxOne', 'boxTwo']};
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
document.addEventListener('mousedown', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClick);
}
handleClick(event) {
const classes = event.target.classList;
const exists = this.state.wrapperRefs.some(ref => classes.contains(ref));
if(!exists) {
this.setState({onClick: !this.state.onClick});
}
}
render() {
return (
<section>
<div className="boxOne container" />
<div className="boxTwo" />
<div>{this.state.onClick ? "On" : "Off"}</div>
</section>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
.boxOne {
height: 100px;
width: 100px;
background: pink;
}
.boxTwo {
margin: 30px;
height: 50px;
width: 70px;
border: solid black 2px;
background: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>