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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30619285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:28:02  来源:igfitidea点击:

Detect whether input element is focused within ReactJS

javascriptnode.jsreactjs

提问by HelpMeStackOverflowMyOnlyHope

How can I detect whether an input element such as the following is currently focused within a ReactJS render function?

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

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

回答by David Hellsing

You can run something like this anytime as long as the input node is mounted and there is a reference to it:

只要输入节点已安装并且有对它的引用,您就可以随时运行这样的程序:

const ReactDOM = require('react-dom')

if ( document.activeElement === ReactDOM.findDOMNode(this.refs.searchInput) )

You will have to add a reference to the input element:

您必须添加对输入元素的引用:

<input ref="searchInput" ...

You should not do this in the rendermethod though, because the input node might not be mounted yet. Use a lifecycle method like componentDidUpdateor componentDidMount.

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

Another way would be to add event listeners for the focusand blurevents inside the input field:

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

<input type="text" onFocus={this.onFocus} onBlur={this.onBlur}...

Then set states in the handlers and check that state in the render method.

然后在处理程序中设置状态并在渲染方法中检查该状态。

onBlur: function() {
    this.setState({ focused: false })
},
onFocus: function() {
    this.setState({ focused: true })
},
render: function() {
    if ( this.state.focused ) {
        // do something
    }
    <input onFocus={this.onFocus} onBlur={this.onBlur}...
}

Note that this will call a re-render each time the node is focused or blurred (but this is what you want, right?)

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

回答by Marcos Abreu

I started with the answer given by David, where he describes two methods, and they both worked for me, but I had concerns about both:

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

  1. On the first case it uses findDOMNode, what has some disadvantages: at minimum its use is discouraged, and it can easily be implemented in a way that it is considered an anti-pattern; and also it can make the code slower, by bypassing the virtual DOM and working with the DOM directly.

  2. On the second option, create and manage a component state only to find that answer seems too much work, can easily get out of sync, and can cause the component to re-render unnecessarily.

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

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

So trying to explore more the issue I came up with the following solution:

所以试图探索更多的问题,我想出了以下解决方案:

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

The same comment on David's answer applies:

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

You should not do this in the render method though, because the input node might not be mounted yet. Use a lifecycle method like componentDidUpdate or componentDidMount.

不过,您不应在渲染方法中执行此操作,因为输入节点可能尚未安装。使用像 componentDidUpdate 或 componentDidMount 这样的生命周期方法。

Advantages:

好处:

  • uses the current component properties (what are immutable values)
  • don't require state management, and therefore won't cause unnecessary re-rendering
  • don't required DOM transversing, so performance should be as good as it gets
  • it doesn't require to create a component reference
  • 使用当前的组件属性(什么是不可变值)
  • 不需要状态管理,因此不会导致不必要的重新渲染
  • 不需要 DOM 遍历,因此性能应该尽可能好
  • 它不需要创建组件引用

Requirements:

要求:

  • your component should have and idproperty that is passed to the form element you want to check (what is most likely the case anyway)
  • 您的组件应该具有id传递给您要检查的表单元素的属性(无论如何最有可能是这种情况)