提问人:Digitalwolf 提问时间:6/25/2023 最后编辑:Digitalwolf 更新时间:7/4/2023 访问量:50
React 输入 - 更新输入时保持光标位置
React inputs - maintaining cursor positions when updating inputs
问:
我创建了一个输入,该输入为用户输入的字符添加一千个分隔符。我已经实现了代码,以防止当代码添加或删除一千个分隔符时,光标在输入的末尾重新定位。但是,当光标直接放在千位分隔符之前或之后时,分别按 delete 或退格键不会删除字符。如何修改代码以启用此功能?
此外,有没有一种简洁的方法可以在 React 中使用这些功能创建输入?
我的代码如下:
import React, { useState, useRef } from 'react';
const NumericInput = () => {
const [value, setValue] = useState('');
const inputRef = useRef(null);
const onKeyDown = (e) => {
const inputElement = inputRef.current;
const caretStart = inputElement.selectionStart;
const caretEnd = inputElement.selectionEnd;
if (e.key === 'Backspace' && caretStart === caretEnd && caretStart > 0) {
const previousChar = inputElement.value.charAt(caretStart - 1);
if (previousChar === ',' || previousChar === ' ') {
e.preventDefault();
inputElement.setSelectionRange(caretStart - 1, caretEnd - 1);
return;
}
}
if (e.key === 'Delete' && caretStart === caretEnd && caretEnd < inputElement.value.length) {
const nextChar = inputElement.value.charAt(caretStart);
if (nextChar === ',' || nextChar === ' ') {
e.preventDefault();
inputElement.setSelectionRange(caretStart + 1, caretEnd + 1);
return;
}
}
if (!/^-?\d*$/g.test(value) && e.key !== '-' && e.key !== 'Backspace') {
e.preventDefault();
}
};
const onChange = (e) => {
const inputValue = e.target.value.replace(/[^0-9-]/g, '');
setValue(inputValue);
const inputElement = inputRef.current;
const caretPosition = Math.max(0, inputElement.selectionStart + (formatValue(inputValue).match(/,/g) || []).length - (formatValue(value).match(/,/g) || []).length);
inputElement.value = formatValue(inputValue);
inputElement.setSelectionRange(caretPosition, caretPosition);
};
const formatValue = (value) => (value ? value.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '');
return (
<input
ref={inputRef}
placeholder='Type Number'
type='text'
onKeyDown={onKeyDown}
onChange={onChange}
value={formatValue(value)}
/>
);
};
export default NumericInput;
任何帮助将不胜感激。谢谢!
答:
1赞
Paulo Fernando
6/25/2023
#1
你是说这样?
import React, { useState, useRef } from 'react';
const NumericInput = () => {
const [value, setValue] = useState('');
const inputRef = useRef(null);
const onKeyDown = (e) => {
const inputElement = inputRef.current;
const caretStart = inputElement.selectionStart;
const caretEnd = inputElement.selectionEnd;
if (e.key === 'Backspace' && caretStart === caretEnd && caretStart > 0) {
const previousChar = inputElement.value.charAt(caretStart - 1);
if (previousChar === ',' || previousChar === ' ') {
inputElement.setSelectionRange(caretStart - 1, caretEnd - 1);
return;
}
}
if (e.key === 'Delete' && caretStart === caretEnd && caretEnd < inputElement.value.length) {
const nextChar = inputElement.value.charAt(caretStart);
if (nextChar === ',' || nextChar === ' ') {
inputElement.setSelectionRange(caretStart + 1, caretEnd + 1);
return;
}
}
};
const onChange = (e) => {
const inputValue = e.target.value.replace(/[^0-9-]/g, '');
setValue(inputValue);
const inputElement = inputRef.current;
const caretPosition = Math.max(0, inputElement.selectionStart + (formatValue(inputValue).match(/,/g) || []).length - (formatValue(value).match(/,/g) || []).length);
inputElement.value = formatValue(inputValue);
inputElement.setSelectionRange(caretPosition, caretPosition);
};
const formatValue = (value) => (value ? value.replace(/\B(?=(\d{3})+(?!\d))/g, ',') : '');
return (
<input
ref={inputRef}
placeholder='Type Number'
type='text'
onKeyDown={onKeyDown}
onChange={onChange}
value={formatValue(value)}
/>
);
};
export default NumericInput;
但是这个库似乎运行良好:
https://www.npmjs.com/package/react-number-format
import { NumericFormat } from "react-number-format";
export default function MainComponent() {
return (
<NumericFormat
thousandSeparator={true}
/>
);
};
评论