当用户点击菜单时如何保持焦点?

时间:2018-04-18 10:58:27

标签: javascript html reactjs browser

我有以下要求:

  • 显示输入字段。
  • 显示菜单。
  • 当输入栏具有焦点时,显示菜单。
  • 如果输入字段失去焦点,请隐藏菜单。
  • 如果单击该菜单,即使输入字段失去焦点,也要保留菜单。

要重现我的问题:   - 将光标放在输入字段中   - 单击菜单

预期:   - 菜单仍然可见

实际值:   - 菜单消失

这在React中应该是直截了当的,但我还没有能够以最明显的方式解决这个问题,并且想知道它是什么,我忽视了。

class App extends React.Component {
  constructor() {
    super();
    this.state = {};
    this.handleFocus = this.handleFocus.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
  }

  handleFocus() {
    this.setState({ hasFocus: true });
  }

  handleBlur() {
    this.setState({ hasFocus: false});
  }

  handleMenuClick() {
    this.setState({ hasFocus: true });
  }

  render() {
    const { hasFocus } = this.state;

    const menuInstance = (
      <div
        onClick={this.handleMenuClick}
        tabIndex="0"
      >
        Some menu
      </div>
    );

    return (
      <div>
        <h1>Focus issue</h1>
        <p>How do I retain focus if the user clicks on the menu item?</p>
        <input
          onBlur={this.handleBlur}
          onFocus={this.handleFocus}
          defaultValue="some value"
        />
        { hasFocus && menuInstance }
      </div>
    );
  }
}

现场演示:http://jsbin.com/zixuhoj/6/edit?js,console,output

2 个答案:

答案 0 :(得分:4)

您正在侦听模糊和点击事件。在单击事件之前触发模糊事件,因此永远不会调用handleMenuClick

相反,您可以收听onMouseDown并为menuClicked或类似内容设置标记,并在blur事件中查看该标记。

演示可以在这里找到:http://jsbin.com/buzisepafu/1/edit?js,console,output

class App extends React.Component {
  constructor() {
    super();
    this.state = {};
    this.handleFocus = this.handleFocus.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.handleMenuClick = this.handleMenuClick.bind(this);
  }

  handleFocus() {
    this.setState({ hasFocus: true });
  }

  handleBlur() {
    if (!this.state.menuClicked) {
      this.setState({ hasFocus: false});
    }
  }

  handleMenuClick (event) {
    this.setState({ menuClicked: true });
  }

  render() {
    const { hasFocus } = this.state;

    const menuInstance = (
      <div
        className="menu"
        onMouseDown={this.handleMenuClick}
        tabIndex="0"
      >
        Some menu
      </div>
    );

    return (
      <div>
        <h1>Focus issue</h1>
        <p>How do I retain focus if the user clicks on the menu item?</p>
        <input
          onBlur={this.handleBlur}
          onFocus={this.handleFocus}
          defaultValue="some value"
        />
        { hasFocus && menuInstance }
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

答案 1 :(得分:0)

我发现了一种不同的方法,在我的环境中,用户只有Chrome,我将onBlur处理程序放在外div上,并检查relatedElement上的blur是否div 1}}事件位于外部nth_value()内部或不是。

随时问你是否愿意我详细说明。