单击时防止触发焦点事件

时间:2019-06-18 20:24:03

标签: javascript reactjs

我目前正在尝试使用React创建自己的下拉组件。当组件获得焦点时,它应该打开选项。而且,您还应该能够在单击时切换选项。

我创建了一个small example来重制此案。

问题是,单击未聚焦的组件时,聚焦和单击事件都将触发,这将打开和关闭选项。元素集中之后,单击事件将按预期方式工作。也使用选项卡获得焦点正在工作。

我没有很好的解决方案来防止这种行为。 event.stopPropation()不起作用,因为这些是同一元素上的2个不同的事件。我唯一的解决方案是具有“ hasFocus”状态,并将其设置为100ms的短暂延迟,然后在onClick函数中进行检查。

当前行为:下拉菜单元素未定位。单击该元素将触发焦点并单击事件,从而导致

ShowOptions: true
ShowOptions: false

所以这些选项只是闪烁而后会被隐藏

预期的行为:触发焦点或单击事件并显示选项。

也许您对这个问题有更好的解决方案。

2 个答案:

答案 0 :(得分:1)

如您所说:

  

触发焦点或单击事件并显示选项。

因此,您需要使用或||运算符:{(isOpen.isClicked || isOpen.isFocused) && <div>Options</div>}

const Dropdown = () => {
  const [isOpen, setIsOpen] = useState({ isFocused: false, isClicked: false });

  const onFocus = () => {
    setIsOpen(prev => ({ ...prev, isFocused: true }));
  };

  const onBlur = () => {
    setIsOpen({ isFocused: false, isClicked: false });
  };

  const onClick = () => {
    setIsOpen(prev => ({
      isClicked: !prev.isClicked,
      isFocused: false
    }));
  };

  return (
    <React.Fragment>
      <Container
        onFocus={onFocus}
        onBlur={onBlur}
        alignItems="stretch"
        onClick={onClick}
      >
      ...
      </Container>
      {(isOpen.isClicked || isOpen.isFocused) && <div>Options</div>}
    </React.Fragment>
  );
};

演示:

Edit Q-56656562

答案 1 :(得分:0)

我通过添加mousedown和mouseup事件解决了我的问题。在焦点事件之前触发Mousedown(以及触摸事件)。因此,我可以在单击元素时“跳过”焦点案例。

  const [showValues, setShowValues] = useState(false);
  const [mouseDown, setMouseDown] = useState(false);

  const onFocus = e => {
    if (!mouseDown) {
      setShowValues(true);
      console.log("focus");
    }
  };

  const onBlur = e => {
    setShowValues(false);
    console.log("blur");
  };

  const onClick = e => {
    setShowValues(!showValues);
    console.log("click");
  };

  const onMouseDown = () => {
    setMouseDown(true);
  };

  const onMouseUp = () => {
    setMouseDown(false);
  };