在onFocus触发时做出反应以防止onClick触发

时间:2019-09-02 11:15:42

标签: javascript reactjs dom-events

我的字段onClick事件切换一个下拉列表,onFocus事件将其打开。
当触发onFocus事件时,随后触发onClick事件并关闭新打开的下拉菜单。 如果ononFocus被触发,如何防止触发Click?

preventDefault和stopPropagation不起作用,两个事件始终被触发

<TextInputV2
  label={label}
  onChange={handleInputOnChange}
  onClick={handleOnClick}
  onFocus={handleOnFocus}
  onKeyUp={handleInputOnKeyUp}
  readOnly={!searchable}
  value={inputValue}
/>

.......

  const handleOnFocus = (event: React.FocusEvent): void => {
    if (!isOpen) {
      changeIsOpen(true)
    }
  }

  const handleOnClick = (event: React.SyntheticEvent): void => {
    if (!searchable) {
      toggleOpen()
    }
  }

2 个答案:

答案 0 :(得分:1)

您将需要将onClick更改为onMouseDown。由于事件顺序为

  
      
  • 鼠标按下
  •   
  • 更改(针对重点输入)
  •   
  • 模糊(在焦点元素上)
  •   
  • 重点
  •   
  • 鼠标
  •   
  • 单击
  •   
  • dblclick
  •   

来自:this answer

您要在焦点事件之前阻止Default / stoPropagation,这意味着必须在触发焦点事件之前使用“ onMouseDown”正确停止它。

在您的情况下,它将是:

<TextInputV2
  label={label}
  onChange={handleInputOnChange}
  onMouseDown={handleOnClick}
  onFocus={handleOnFocus}
  onKeyUp={handleInputOnKeyUp}
  readOnly={!searchable}
  value={inputValue}
/>
 const handleOnClick = (event) => {
    event.preventDefault()
    event.stopPropagation()
  if (!searchable) {
   toggleOpen()
  }
}

答案 1 :(得分:0)

https://jsfiddle.net/reactjs/69z2wepo/

class Hello extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
        text: 'hello'
    }

    this.lastFocus = 0;
  }

  handleOnClick(ev) {
    const now = new Date().getTime();
    console.log('diff since lastFocus');
    console.log(now - this.lastFocus);
    if (now - this.lastFocus < 200) {
        return;
    }
    const newText = this.state.text + 'c';
    this.setState({text:newText})
  }

  handleOnFocus(ev) {
    this.lastFocus = new Date().getTime();

    const newText = this.state.text + 'f';
    this.setState({text:newText});
  }

  render() {
    return <div>
      <input name="" id="" cols="30" rows="10"
        value={this.state.text}

         onClick={this.handleOnClick.bind(this)}
          onFocus={this.handleOnFocus.bind(this)}
      ></input>
    </div>;
  }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

您存储lastFocus的时间-不存储在this.state中,因为它是异步更新的,并且您不能依靠在onClick处理程序中通过在onFocus处理程序中调用setState进行更新。您将其直接放在实例上并直接更新。

您可以使用一条经验法则,即如果最后一次焦点在200ms内,则此onClick处理程序与onFocus处理程序来自同一事件,因此不会运行其余onClick处理程序。

我的摆弄显然不是您的整个用例,我只是将f放在焦点上,将c放在点击上添加到输入文本中。

相关问题