使用React使用onkeydown在文本结束时使用cart/text-cursor进行焦点输入元素

发布于 2025-02-03 11:12:49 字数 738 浏览 2 评论 0原文

我的组件中有两个输入字段:

const MyComponent = () => {

  const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === 'ArrowLeft') {
      ref.current?.setSelectionRange(value.length, value.length)
      ref.current?.focus()
    }
  }

  const [value, setValue] = useState('1234')
  const ref = useRef<HTMLInputElement>(null)

  return (
    <>
      <input
        onChange={({target}) => setValue(target.value)}
        value={value}
        ref={ref}
        type={'text'}/>

      <input
        onKeyDown={onKeyDown}
        type={'text'}/>
    </>
  )
}

当我在第二个输入中击中左箭头键时,应该集中第一个输入,并且光标应在输入文本的末尾。

但是光标处于错误的位置。为什么这不起作用?

I have two input fields in my component:

const MyComponent = () => {

  const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === 'ArrowLeft') {
      ref.current?.setSelectionRange(value.length, value.length)
      ref.current?.focus()
    }
  }

  const [value, setValue] = useState('1234')
  const ref = useRef<HTMLInputElement>(null)

  return (
    <>
      <input
        onChange={({target}) => setValue(target.value)}
        value={value}
        ref={ref}
        type={'text'}/>

      <input
        onKeyDown={onKeyDown}
        type={'text'}/>
    </>
  )
}

When i hit the left arrow-key on the second input, the first input should be focused, and the cursor should be at the end of the input text.

But the cursor is at the wrong place. Why is this not working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

杀手六號 2025-02-10 11:12:49

光标是否向最后一个角色的左侧移动一个位置?

有趣的是,当使用onkeyup(键的发布)而不是onkeydown时,问题似乎消失了。我列出了该解决方案,然后还有其他几个示例,其中包括下面的解释。

解决方案

import { useRef, useState } from "react";

const MyComponent = () => {
  const [value, setValue] = useState("1234");
  const ref = useRef(null);

  const onKeyUp = (event) => {
    if (event.key === "ArrowLeft") {
      const textInput = ref.current;
      const len = value.length;

      textInput.setSelectionRange(len, len);
      textInput.focus();
    }
  };

  return (
    <>
      <input
        onChange={({ target }) => setValue(target.value)}
        value={value}
        ref={ref}
        type={"text"}
      />

      <input onKeyUp={onKeyUp} type={"text"} />
    </>
  );
};

export default MyComponent;

https://codesandbox.io/s/cursor-cursor-cursor-endor-endor-end-end of -input-onkeyup-x6ekke

说明

我的猜测是因为onkeyup自然遵循onkeydown,当我们在React中接收OnKeydown事件时,根据您的示例代码,发生以下顺序(或一般说类似这样的事情):

内部onkeydown ...

  1. 我们的光标已移至文本输入的末尾。<<<<<<<<<<< /p>

    ref.current?.setselectionrange(value.length,value.length)

  2. 文本输入接收焦点。

    ref.current?.focus()

  3. 然后,左箭头键的释放onkeyup要在DOM中运行的事件(我们没有在React中执行此操作) em>现在,由于上述步骤2的结果,焦点是在文本输入上。输入重点是将左箭头键按/释放左箭头键的默认行为是将光标一个位置移至左侧,将其从输入文本末端放置一个位置。

其他示例/解决方案,

如果您坚持使用onkeydown,这里还有其他几个示例。

event.preventdefault()

const onKeyDown = (event) => {
  if (event.key === "ArrowLeft") {
    event.preventDefault();
    const textInput = ref.current;
    const len = value.length;
    textInput.setSelectionRange(len, len);
    textInput.focus();
  }
};

settimeout()

const onKeyDown = (event) => {
  if (event.key === "ArrowLeft") {
    setTimeout(() => {
      const textInput = ref.current;
      const len = value.length;
      textInput.setSelectionRange(len, len);
      textInput.focus();
    }, 0);
  }
};

https://codesandbox.io/s/cursor-end-of-input-example-h1yrdr

我的猜测是,这些解决方法有效地阻止了浏览器,从而超出了本机键向下触发或延迟我们的处理程序从运行到 分别启动了本机事件。

Was the cursor moving one position to the left of the last character?

Interestingly, when using onKeyUp (the release of the key) rather than onKeyDown the issue seems to go away. I've listed that solution followed by a couple other examples with explanations below.

Solution

import { useRef, useState } from "react";

const MyComponent = () => {
  const [value, setValue] = useState("1234");
  const ref = useRef(null);

  const onKeyUp = (event) => {
    if (event.key === "ArrowLeft") {
      const textInput = ref.current;
      const len = value.length;

      textInput.setSelectionRange(len, len);
      textInput.focus();
    }
  };

  return (
    <>
      <input
        onChange={({ target }) => setValue(target.value)}
        value={value}
        ref={ref}
        type={"text"}
      />

      <input onKeyUp={onKeyUp} type={"text"} />
    </>
  );
};

export default MyComponent;

https://codesandbox.io/s/cursor-end-of-input-onkeyup-x6ekke

Explanation

My guess is that because onKeyUp naturally follows onKeyDown, when we receive the onKeyDown event in React, per your example code, the following sequence occurs (or generally speaking something like this is happening):

Inside onKeyDown...

  1. Our cursor is moved to the very end of the text input.

    ref.current?.setSelectionRange(value.length, value.length)

  2. The text input receives focus.

    ref.current?.focus()

  3. Then, the release of the left arrow key causes onKeyUp event to run in the DOM (we haven't done anything to handle this in React) while the focus is now on the text input as a result of step 2 above. The default behavior pressing/releasing the left arrow key while the input has focus is to move the cursor one position to the left, placing it one position from the end of the input text.

Other Examples/Solutions

If you stick with the use of onKeyDown, here are a couple other examples.

event.preventDefault()

const onKeyDown = (event) => {
  if (event.key === "ArrowLeft") {
    event.preventDefault();
    const textInput = ref.current;
    const len = value.length;
    textInput.setSelectionRange(len, len);
    textInput.focus();
  }
};

setTimeout()

const onKeyDown = (event) => {
  if (event.key === "ArrowLeft") {
    setTimeout(() => {
      const textInput = ref.current;
      const len = value.length;
      textInput.setSelectionRange(len, len);
      textInput.focus();
    }, 0);
  }
};

https://codesandbox.io/s/cursor-end-of-input-example-h1yrdr

My guess is that these workarounds effectively block the browser from firing the native key down and up events altogether or delay our handler from running until after the native events have fired, respectively.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文