当输入框获得焦点时如何设置光标位置?

4

当输入框聚焦时,我需要将光标(插入符号)设置为第一个位置:

CodeSandbox

我猜下面的代码应该是可行的,但实际上它并不能正常工作。不过,如果由按钮点击触发,则可以正常工作。

我做错了什么?

import React, { ChangeEventHandler, useRef, useState } from "react";

const setCaretPosition = (ctrl, pos) => {
  // Modern browsers
  if (ctrl.setSelectionRange) {
    ctrl.focus();
    ctrl.setSelectionRange(pos, pos);
  }
};

export default function App() {
  
  const [value,setValue] = useState("123456789");
  const input_ref = useRef(null);

  const onFocus = () => {
    setCaretPosition(input_ref.current, 0);
  };

  const onChange = (event) => {
    setValue(event.target.value);
  };

  const buttonClick = () => {
    setCaretPosition(input_ref.current, 0);
  };

  return (
    <React.Fragment>
      <div>
        <input 
          type="text" 
          onChange={onChange} 
          value={value} 
          ref={input_ref}
          onFocus={onFocus}
        />
        <button onClick={buttonClick}>Reset cursor</button>
      </div>
    </React.Fragment>
  );
}

使用您的 CodeSandbox 链接,在 Firefox 中它对我来说运行良好。我点击文本输入框,光标在开头。 - Gregg
用户设置光标后,你会重新聚焦光标,这很奇怪。 - epascarello
@epascarello,将会有一个类型为DD-MM-YYYY的掩码存在。因此,我想确保光标在开头。在移动设备上通常很难选择掩码的确切开头。 - cbdeveloper
1个回答

3
实际问题在于onFocus事件,而不是你的代码。似乎你的代码将光标放在开头,然后focus事件将其放回到结尾。因此,将你的代码延迟到focus事件之后再执行,可以解决这个问题。
我尝试将它放入setTimeout中,它立即开始工作。- 使用你的代码沙盒进行测试。
setTimeout(() => {
      setCaretPosition(input_ref.current as HTMLInputElement, 0);
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接