我正在尝试在React中创建一个select2样式组件。
我有90%的功能下降,我无法理解的一点是hiding the result box when the user clicks away
渲染方法是:
render() {
let resultBlock;
if (this.state.showSearch) {
resultBlock = (
<div className="search-input-container" onBlur={this.onBlur}>
<div className="search-input-results">
<input
type="text"
name={this.props.name}
placeholder={this.props.placeholder}
className="form-control"
onChange={this.inputKeyUp}
autoComplete="false" />
<ul>
{this.state.items.map((item, i) => <li key={i} data-value={item.id} onClick={this.itemSelected} className={item.isSelected ? 'selected' : ''}>{item.text}</li>)}
</ul>
</div>
</div>
);
}
let displayBlock;
if (this.props.value.text) {
displayBlock = this.props.value.text;
} else {
displayBlock = <span className="placeholder">{this.props.placeholder}</span>;
}
return (
<div className="form-group">
<label htmlFor={this.props.name}>{this.props.label}:</label>
<div className="form-input">
<div className="searchable-dropdown" onClick={this.revealSearch}>
{displayBlock}
<div className="arrow"><i className="fa fa-chevron-down" aria-hidden="true" /></div>
</div>
{resultBlock}
</div>
</div>
);
}
我试过移动onBlur={this.onBlur}
,但只有<input...
在点击之前有焦点时才会触发。
这不是那么复杂,我想到的唯一方法是将全局点击处理程序附加到页面,并通过差异点击来了解用户是否未点击我的组件。但这似乎过度设计了。
如何实现这一目标?
答案 0 :(得分:2)
我通过以下方式实现了此功能:
将它放在构造函数中:
this.windowClick = this.windowClick.bind(this);
(从dfsq所说的)把它放在componentDidMount:
中if (window) {
window.addEventListener('click', this.windowClick, false);
}
此事件处理程序:
windowClick(event) {
event.preventDefault();
if (event.target.classList.contains('searchable-marker')) {
return;
} else {
this.setState({
showSearch: false
});
}
}
searchable-marker
只是一个课程,我把所有的div,ul,s,li和输入放在一起,以确保如果我点击其中一个,它就不会#39;关闭包装盒。
添加卸载:
componentWillUnmount() {
window.removeEventListener('click', this.windowClick, false);
}
答案 1 :(得分:0)
你可以尝试做的是onBlur你可以改变this.state.showSearch = false的值,当满足这个条件时,添加一个className =&#34; hide&#34; (隐藏{display:none})创建一个自定义函数,该函数将类名作为字符串返回。