Javascript 检测输入元素是否集中在ReactJS中

Javascript 检测输入元素是否集中在ReactJS中,javascript,node.js,reactjs,Javascript,Node.js,Reactjs,如何检测以下输入元素当前是否集中在ReactJS渲染函数中 <input type="text" style={searchBoxStyle} placeholder="Search"></input> 您可以对照document.activeElement进行检查,只要安装了输入节点并且有对它的引用: const searchInput = React.useRef(null) if (document.activeElement === searchInpu

如何检测以下输入元素当前是否集中在ReactJS渲染函数中

<input type="text" style={searchBoxStyle} placeholder="Search"></input>   

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

const searchInput = React.useRef(null)

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

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

请注意,每当节点聚焦或模糊时,这将调用重新渲染(但这是您想要的,对吗?

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

  • 在第一种情况下,它使用的是
    findDOMNode
    ,它有一些缺点:至少不鼓励使用它,而且它可以以一种被认为是反模式的方式轻松实现;它还可以通过绕过虚拟DOM并直接使用DOM来降低代码的速度

  • 在第二个选项中,创建和管理组件状态时发现答案似乎太多工作,很容易失去同步,并可能导致组件不必要地重新渲染

  • 因此,在尝试进一步探讨这个问题后,我提出了以下解决方案:

    if (this.props.id === document.activeElement.id) {
      // your code goes here
    }
    
    对David回答的相同评论适用于:

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

    优点:

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

    • 组件应该有一个
      id
      属性,该属性传递给要检查的表单元素(很可能是这种情况)
    使用挂钩:

    首先创建并初始化引用

    const yourElement = useRef(null)
    
    然后使用刚刚创建的引用标记元素:

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

    使用功能组件,您可以确定当前输入是否具有焦点:

    import React from "react";
    
    export default function App() {
      const ref = React.createRef(null);
    
      const handleMouseOut = (currentRef) => {
    
        if (document.activeElement === currentRef) {
          console.log("Yesss");
        }
      };
      return (
        <div className="App">
          <input
            type="text"
            ref={ref}
            onMouseOut={() => handleMouseOut(ref.current)}
          />
        </div>
      );
    }
    
    从“React”导入React;
    导出默认函数App(){
    const ref=React.createRef(null);
    常量handleMouseOut=(currentRef)=>{
    if(document.activeElement==currentRef){
    控制台日志(“Yesss”);
    }
    };
    返回(
    handleMouseOut(参考电流)}
    />
    );
    }
    

    实例:

    根据您想要做的事情,您可以使用
    onFocus
    (React 17)或
    onBlur
    (React 16)来实现这些事情处于焦点时所需的功能。

    使用挂钩的方法更简单

    进口

    import React, {useState} from "react";
    
    定义

    const [isMyInputFocused, setIsMyInputFocused] = useState(false);
    
    在您选择的输入中,只需添加

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

    从现在起,您可以根据自己的意愿访问
    isMyInputFocused

    findDOMNode
    已移至
    ReactDOM
    @JamesBrierley下,谢谢!已验证并编辑答案以反映React.findDOMNode()已不存在,但多年后找到此帖子的任何人都可以作为ReactDOM.findDOMNode()使用:在React 16.x及以上版本中,不再建议使用
    refs
    这样,应使用新的
    React.createRef()
    功能。更多信息:我用第二种方法解决了我的问题。显然,没有什么是
    refs.current.hasFocus
    document.activeElement与您的ref进行比较,因此:
    document.activeElement==this.ref.current
    这是一个“psudeo焦点”并且不能很好地扩展:例如:如果有10个输入,则必须提升此状态并开始管理引用,否则需要将此状态应用于每个输入,并且存在失去同步的风险
    const [isMyInputFocused, setIsMyInputFocused] = useState(false);
    
                        onBlur={() => setIsMyInputFocused(false)}
                        onFocus={() => setIsMyInputFocused(true)}