【问题标题】:React: Fire a function when the element is blurredReact:当元素模糊时触发一个函数
【发布时间】:2020-10-20 13:04:29
【问题描述】:

我试图在元素失去焦点时触发一个函数,但似乎在我的 React 应用程序中无法识别模糊事件。我不清楚我错过了什么。下面的 sn-p 就在我的组件中的 return 方法之上。

我的 div 带有 ref {infoWindow}。目前,当我在 div 窗口内单击然后退出时,console.log 没有输出任何内容。

const infoWindow = useRef<HTMLDivElement>(null);
if (infoWindow.current) {
  infoWindow.current.addEventListener('blur', (event) => {
    console.log(`We've been blurred`);
  });
}

【问题讨论】:

  • 我认为部分组件代码在这种情况下可能会有所帮助。您是否在任何元素上使用了此参考?这是一个基于功能组件/类的组件吗?

标签: javascript reactjs


【解决方案1】:

这不是你在 React 中引入副作用的方式,向元素添加事件监听器是一种副作用,应该在 useEffect 中创建副作用。

这是您的代码的问题

const infoWindow = useRef<HTMLDivElement>(null);
// assume your component gets rendered once - at the initial render the component is not mounted in dom yet
// then infoWindow.current is null, and an event listener will not be added. This is what is probably happening with you.
// assume your component is rendered 1000 times, then you will add 999 event listeners, which is definitely not what you want
if (infoWindow.current) {
  infoWindow.current.addEventListener('blur', (event) => {
    console.log(`We've been blurred`);
  });
}

解决办法是使用useEffect

useEffect(() => {
  if (infoWindow.current) {
     const handler = (event) => {
       console.log(`We've been blurred`);
     }
     // notice that i get a reference to the element here, so i can safely use it in the clean function
     const element = infoWindow.current
     element.addEventListener('blur', handler);
     // this is a clean function that will be called to clear the side effects you just introduced
     return () => element.removeEventListener('blur', handler);

  }


}, [])

编辑 上面说的是对的,但是你还有一个问题,div元素默认不接收焦点事件,所以不会模糊。如果你想让一个元素模糊和聚焦,然后添加 tabIndex 到它,所以在你的 div 上做

<div tabIndex={0}>...</div>

【讨论】:

  • 我已将此添加到我的代码中,但它也不会触发模糊事件。当我在 div 之外单击时,什么也没有发生。
  • 我什至尝试使用“强制元素状态”事件并单击:焦点,但取消单击也无济于事。这很奇怪。
  • @pingeyeg 这并不奇怪,默认情况下 div 元素不接收焦点事件,除非您将 tabIndex 添加到它们 - 或使它们可内容编辑 - 请参阅我的编辑以解决您的问题
  • 所以,我注意到如果我不在 div 元素内单击,则不会触发 blur 事件。这个 dev 元素里面只有文本,所以可能永远不会被点击,因此我相信我需要在 div 出现后触发一个焦点事件。
  • @pingeyeg 很好,我已经解决了问题中的问题,但无论如何,您似乎在尝试使用 div 时做错了事,但这超出了这个问题的范围
【解决方案2】:

为什么不直接在 div 中添加一个 onBlur 事件监听器?

https://reactjs.org/docs/accessibility.html#mouse-and-pointer-events

【讨论】:

  • 我也试过了,但仍然没有触发任何东西。
  • 你确定它正在集中注意力吗?
猜你喜欢
  • 2018-05-02
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多