【问题标题】:Incorrect focusout trigger when changing focus within container在容器内更改焦点时触发不正确的焦点输出
【发布时间】:2021-06-16 20:52:46
【问题描述】:

假设我有下面的代码结构。如果我在我的红色容器(输入之一)中聚焦一个元素,focusin 事件将触发。同样,如果我在红色容器外单击,focusout 事件将触发。

但是,如果我单击其中一个输入元素,然后直接单击另一个,focusoutfocusin 事件都会快速连续触发。

有没有一种简单的方法可以避免这种情况,或者找出是否可以忽略第二个 focusout 事件,因为焦点实际上停留在相关元素内,除了丑陋的解决方案,例如在第一个 focusout 事件上设置标志和等待渲染滴答以查看是否发生了另一个 focusin 事件?

document.getElementById("el").addEventListener("focusin", 
  () => document.getElementById("out").innerHTML += "focusin<br/>");
document.getElementById("el").addEventListener("focusout", 
  () => document.getElementById("out").innerHTML += "focusout<br/>");
<div id="el" style="background-color: red; padding: 4px">
<input />
<input />
</div>
<div id="out">

</div>

【问题讨论】:

标签: javascript html focus lost-focus


【解决方案1】:

由于似乎没有一个简单的解决方案,我编写了等待下一个渲染滴答声的丑陋解决方案。我把它写成可重用的 React 钩子,所以如果它对某人有帮助,就在这里。

export const useFocusWithin = (
  element: HTMLElement | undefined,
  onFocusIn?: () => void,
  onFocusOut?: () => void,
) => {
  const [focusWithin, setFocusWithin] = useState(false);
  const isLoosingFocusFlag = useRef(false);

  useHtmlElementEventListener(element, 'focusin', () => {
    setFocusWithin(true);
    onFocusIn?.();
    if (isLoosingFocusFlag.current) {
      isLoosingFocusFlag.current = false;
    }
  });
  
  useHtmlElementEventListener(element, 'focusout', (e) => {
    isLoosingFocusFlag.current = true;
    setTimeout(() => {
      if (isLoosingFocusFlag.current) {
        onFocusOut?.();
        isLoosingFocusFlag.current = false;
        setFocusWithin(false);
      }
    });
  });

  return focusWithin;
};

export const useHtmlElementEventListener = <K extends keyof HTMLElementEventMap>(
  element: HTMLElement | undefined, type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any) => {
  useEffect(() => {
    if (element) {
      element.addEventListener(type, listener as any);
      return () => element.removeEventListener(type, listener as any);
    }
  }, [element, listener, type]);
};

【讨论】:

    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多