如何在React中将下拉菜单的位置适应到当前文本字段中的光标位置?

huangapple go评论53阅读模式
英文:

How can I fit the position of dropdown at current cursor position in textfield in react?

问题

在我的代码中,当用户键入$符号时,下拉菜单会显示,这部分代码运行正常。我希望当用户再次输入$符号时,下拉菜单应该设置在光标的最后位置,但现在下拉菜单会移动到我们点击的文本字段上,该如何修复,使下拉菜单仅相对于当前文本的光标位置移动?

这部分代码正常,但每当我们在第一个位置键入$符号时,下拉菜单应该从最后位置移动到初始位置,但这没有生效,该如何处理?

import { useState, useRef } from "react";
export default function App() {
  const [value, setValue] = useState("");
  const [show, setShow] = useState(false);
  const [cursor, setCursor] = useState(0);
  const ref = useRef(null);

  const foo = (e) => {
    setValue(e.target.value);
    if (e.nativeEvent.data === "$") {
      setShow(true);
    } else {
      setShow(false);
    }
    setCursor(Math.min(e.target.value?.length, 22) * 8);
  };
  const boo = (e) => {
    console.log(e.clientX);
    setCursor(e.clientX);
  };
  return (
    <div className="App">
      <input value={value} onChange={foo} ref={ref} onKeyDown={boo} />
      {show && (
        <div
          style={{
            width: "210px",
            height: "210px",
            background: "pink",
            marginLeft: cursor + "px",
            position: "absolute",
            left: "2px",
          }}
        >
          -下拉菜单-
        </div>
      )}
    </div>
  );
}
英文:

In my code, dropdown shown when user type $ symbol, this is working fine, I wanted to when user gave $ symbol again that dropdown should be set at last position of curser but now dropdown is moving whatever we have clicked to text field, so how to fix that the dropdown should move relative to the cursor on the current text only?

如何在React中将下拉菜单的位置适应到当前文本字段中的光标位置?

This is fine but whenever we have type $ symbol at the first position dropdown should be move from last to initial position but its not working, so how to deal with that?

如何在React中将下拉菜单的位置适应到当前文本字段中的光标位置?

import { useState, useRef } from &quot;react&quot;;
export default function App() {
  const [value, setValue] = useState(&quot;&quot;);
  const [show, setShow] = useState(false);
  const [cursor, setCursor] = useState(0);
  const ref = useRef(null);

  const foo = (e) =&gt; {
    setValue(e.target.value);
    if (e.nativeEvent.data === &quot;$&quot;) {
      setShow(true);
    } else {
      setShow(false);
    }
    setCursor(Math.min(e.target.value?.length, 22) * 8);
  };
  const boo = (e) =&gt; {
    console.log(e.clientX);
    setCursor(e.clientX);
  };
  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;input value={value} onChange={foo} ref={ref} onKeyDown={boo} /&gt;
      {show &amp;&amp; (
        &lt;div
          style={{
            width: &quot;210px&quot;,
            height: &quot;210px&quot;,
            background: &quot;pink&quot;,
            marginLeft: cursor + &quot;px&quot;,
            position: &quot;absolute&quot;,
            left: &quot;2px&quot;,
          }}
        &gt;
          -DropDown-
        &lt;/div&gt;
      )}
    &lt;/div&gt;
  );
}

答案1

得分: 1

我尝试理解您的问题。因此,您希望在用户键入$并在输入时键入或单击光标时显示下拉框。

您可以使用selectionStart来了解输入字段上的光标位置。

使用您的示例:

import { useState, useRef } from &#39;react&#39;;
export default function App() {
const [value, setValue] = useState(&#39;&#39;);
const [show, setShow] = useState(false);
const [cursor, setCursor] = useState(0);
const ref = useRef(null);
const calculatePosition = position =&gt; Math.min(position, 22) * 8;
const handleChange = e =&gt; {
setValue(e.target.value);
if (e.target.value === &#39;&#39; || !e.target.value.includes(&#39;$&#39;))
setShow(false); // 如果为空或在更改时没有$,则禁用下拉框
else if (e.nativeEvent.data === &#39;$&#39;) setShow(true);
};
const handlePosition = e =&gt; setCursor(calculatePosition(e.target.selectionStart)); // 获取输入中的光标位置
const handleFocus = e =&gt; (e.target.value !== &#39;&#39; &amp;&amp; e.target.value.includes(&#39;$&#39;) ? setShow(true) : null); // 如果不为空并包含$,则显示下拉框
return (
&lt;div className=&#39;App&#39;&gt;
&lt;input
ref={ref}
value={value}
onChange={handleChange}
onClick={handlePosition}
onKeyDown={handlePosition}
onFocus={handleFocus}
onBlur={() =&gt; setShow(false)} // 如果失去焦点,则隐藏下拉框
/&gt;
{show &amp;&amp; (
&lt;div
style={{
width: &#39;210px&#39;,
height: &#39;210px&#39;,
background: &#39;pink&#39;,
marginLeft: cursor + &#39;px&#39;,
position: &#39;absolute&#39;,
left: &#39;2px&#39;,
}}
&gt;
-DropDown-
&lt;/div&gt;
)}
&lt;/div&gt;
);
}
英文:

I tried to understand your problem. So you want to the dropdown show when user type $ and follow your cursor when you type or click on the input.

You can use the selectionStart to know the cursor position on the input.

With your example :

import { useState, useRef } from &#39;react&#39;;
export default function App() {
const [value, setValue] = useState(&#39;&#39;);
const [show, setShow] = useState(false);
const [cursor, setCursor] = useState(0);
const ref = useRef(null);
const calculatePosition = position =&gt; Math.min(position, 22) * 8;
const handleChange = e =&gt; {
setValue(e.target.value);
if (e.target.value === &#39;&#39; || !e.target.value.includes(&#39;$&#39;))
setShow(false); // If is empty or havent $ when change disable the dropdown
else if (e.nativeEvent.data === &#39;$&#39;) setShow(true);
};
const handlePosition = e =&gt; setCursor(calculatePosition(e.target.selectionStart)); // Get cursor position in the input
const handleFocus = e =&gt; (e.target.value !== &#39;&#39; &amp;&amp; e.target.value.includes(&#39;$&#39;) ? setShow(true) : null); // Show the dropdown if isn&#39;t empty and have $
return (
&lt;div className=&#39;App&#39;&gt;
&lt;input
ref={ref}
value={value}
onChange={handleChange}
onClick={handlePosition}
onKeyDown={handlePosition}
onFocus={handleFocus}
onBlur={() =&gt; setShow(false)} // If focus is lose hide the dropdown
/&gt;
{show &amp;&amp; (
&lt;div
style={{
width: &#39;210px&#39;,
height: &#39;210px&#39;,
background: &#39;pink&#39;,
marginLeft: cursor + &#39;px&#39;,
position: &#39;absolute&#39;,
left: &#39;2px&#39;,
}}
&gt;
-DropDown-
&lt;/div&gt;
)}
&lt;/div&gt;
);
}

huangapple
  • 本文由 发表于 2023年2月9日 01:30:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389607.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定