【问题标题】:React Component "closing" when lost focus失去焦点时反应组件“关闭”
【发布时间】:2016-12-20 09:45:43
【问题描述】:

我正在尝试在 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},但只有当&lt;input... 在单击之前获得焦点时才会触发。

不可能那么复杂,我想到的唯一方法是将全局点击处理程序附加到页面,并区分点击以了解用户是否没有点击我的组件。但这似乎被过度设计了。

如何做到这一点?

【问题讨论】:

  • “将全局点击处理程序附加到页面” - 这正是应该这样做的方式。
  • 你是认真的吗?!对……对什么对象、窗口、文档?
  • @CallumLinington,窗口可以工作
  • 我可以在窗口点击处理程序中使用event.preventDefault() 来阻止不需要的点击吗?我也应该分离事件,这应该在 componentWillUnmount 中完成?

标签: javascript reactjs react-redux


【解决方案1】:

我通过以下方式实现了此功能:

把这个放在构造函数中:

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、li 和输入上的一个类,以确保如果我单击其中一个,它不会关闭框。

添加卸载:

componentWillUnmount() {
    window.removeEventListener('click', this.windowClick, false);
}

【讨论】:

  • 您的想法是正确的。最好在componentDidMount中绑定点击事件。 event.preventDefault() 似乎也没用。
【解决方案2】:

您可以尝试做的是 onBlur,您可以更改 this.state.showSearch = false 的值,当满足此条件时,通过创建一个自定义函数添加一个 className="hide" (hide{display: none})将类名作为字符串返回。

【讨论】:

  • 那可不太合适
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 2011-03-23
  • 1970-01-01
  • 2016-09-23
相关资源
最近更新 更多