简体   繁体   English

在 React 中聚焦并单击输入字段

[英]Focus and click input field in React

I am trying to focus and then click input field with the help of useRef hook.我试图集中注意力,然后在 useRef 挂钩的帮助下单击输入字段。 What I am trying to achieve is to open the keyboard of input field in mobile phone browser of both IOS and ANDROID. Unfortunately it doesn't work in my case and I am not sure why.我想要实现的是在 IOS 和 ANDROID 的手机浏览器中打开输入字段的键盘。不幸的是,它在我的情况下不起作用,我不确定为什么。 Note that console log shows clicked.请注意,控制台日志显示已单击。 Here is my code:这是我的代码:

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const inputRef = useRef();

  useEffect(() => {
    waiting();

    inputRef.current.click();
  }, []);

  const waiting = async () => {
    await inputRef.current.focus();
  };
  return (
    <div>
      <input
        ref={inputRef}
        placeholder="input area"
        type="tel"
        onClick={() => {
          console.log("clicked");
        }}
      />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I am trying to reimplement this javascript code by n8jadams IOS show keyboard on input focus in React.我正在尝试通过n8jadams IOS show keyboard on input focus在 React 中重新实现此 javascript 代码。 Not sure if I am on the right track.不确定我是否在正确的轨道上。 This code will ensure that Keyboard will open both on IOS and ANDROID此代码将确保键盘将在 IOS 和 ANDROID 上打开

UPDATE:更新:

got this code but it still doesn't work:得到了这段代码,但它仍然不起作用:

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const inputRef = useRef();
  function focusAndOpenKeyboard(el) {
    if (el) {
      // Align temp input element approx. to be where the input element is
      var __tempEl__ = document.createElement("input");
      __tempEl__.style.position = "absolute";
      __tempEl__.style.top = el.offsetTop + 7 + "px";
      __tempEl__.style.left = el.offsetLeft + "px";
      __tempEl__.style.height = 0;
      __tempEl__.style.opacity = 0;
      // Put this temp element as a child of the page <body> and focus on it
      document.body.appendChild(__tempEl__);
      __tempEl__.focus();

      // The keyboard is open. Now do a delayed focus on the target element
      setTimeout(function () {
        el.focus();
        el.click();
        // Remove the temp element
        document.body.removeChild(__tempEl__);
      }, 100);
    }
  }
  useEffect(() => {
    const element = inputRef.current.querySelector("input, textarea");
    focusAndOpenKeyboard(element);
  }, [inputRef]);

  return (
    <div ref={inputRef}>
      <input placeholder="input area" type="tel" />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I had the same issue last week and was able to resolve it after multiple days of searching and trying different approaches including the one you tried aswell.上周我遇到了同样的问题,经过多天的搜索和尝试不同的方法(包括您尝试过的方法)后能够解决它。 The big point that made a difference to me was the following sentence of this blog post :对我产生影响的重要一点是这篇文的以下句子:

The useEffect handler won't actually run, since React won't re-render after the ref gets attached. useEffect 处理程序实际上不会运行,因为 React 不会在附加 ref 后重新渲染。 In this situation, the React documentation recommends using a callback ref instead.在这种情况下,React 文档建议改用回调 ref。

So I tried it like so:所以我这样尝试:

const input = useRef();

// Puts searchbar in focus on render if mobile and opens the keyboard on both iOS and Android devices
// Source: https://blog.maisie.ink/react-ref-autofocus/#callback-refs
const callbackRef = useCallback(
    (inputElement: HTMLInputElement): void => {
        input.current = inputElement;
        focusAndOpenKeyboard(inputElement, 150);
    },
    [],
);

return (
<div>
  <input placeholder="input area" type="tel" ref={callbackRef}/>
</div>

); );

I hope this helps you even though my answer is a lot later than your question.我希望这对你有帮助,即使我的回答比你的问题晚很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM