检测输入元素是否在 ReactJS 中获得焦点

IT技术 javascript node.js reactjs
2021-05-23 05:12:14

如何检测诸如以下的输入元素当前是否在 ReactJS 渲染函数中聚焦?

<input type="text" style={searchBoxStyle} placeholder="Search"></input>   
4个回答

document.activeElement只要输入节点已安装并且有对它的引用,您就可以进行检查

const searchInput = React.useRef(null)

if (document.activeElement === searchInput.current) {
  // do something
}

return <input type="text" ref={searchInput} />

另一种方法是为输入字段内的focusblur事件添加事件侦听器

const [focused, setFocused] = React.useState(false)
const onFocus = () => setFocused(true)
const onBlur = () => setFocused(false)

return <input type="text" onFocus={onFocus} onBlur={onBlur} />

请注意,每次节点聚焦或模糊时,这都会调用重新渲染(但这正是您想要的,对吧?)

我从大卫给出的答案开始,他描述了两种方法,它们都对我有用,但我对这两种方法都有顾虑:

  1. 在第一种情况下,它使用findDOMNode,有一些缺点:至少不鼓励使用它,并且可以很容易地以被认为是反模式的方式实现;并且它还可以通过绕过虚拟 DOM 并直接使用 DOM 来使代码变慢。

  2. 在第二个选项中,创建和管理组件状态只是发现答案似乎工作量太大,很容易不同步,并且可能导致组件不必要地重新渲染。

所以在尝试更多地探索这个问题之后,我想出了以下解决方案:

if (this.props.id === document.activeElement.id) {
  // your code goes here
}

对大卫回答的相同评论适用:

但是,您不应在该render方法中执行此操作,因为输入节点可能尚未安装。使用生命周期方法,如componentDidUpdatecomponentDidMount

好处:

  • 使用当前的组件属性(它们是不可变的值)
  • 不需要状态管理,因此不会导致不必要的重新渲染
  • 不需要 DOM 遍历,因此性能应该尽可能好
  • 不需要创建组件引用

要求:

  • 您的组件应该有一个id传递给您要检查的表单元素属性(无论如何都很可能是这种情况)

使用钩子:

首先,您创建并初始化您的参考

const yourElement = useRef(null)

然后你用你刚刚创建的引用标记你的元素:

<div ref={yourElement}>Im an DOM node</div>

然后,您使用此逻辑,因为您需要比较document.activeElement文档属性是否等于您引用的 DOM 节点

yourElement.current === document.activeElement

使用钩子有更简单的方法。

进行导入

import React, {useState} from "react";

定义

const [isMyInputFocused, setIsMyInputFocused] = useState(false);

并在您选择的输入中添加

                    onBlur={() => setIsMyInputFocused(false)}
                    onFocus={() => setIsMyInputFocused(true)}

从现在开始,您可以isMyInputFocused根据需要访问