javascript - 如何通过忽略每次按键上的无效字符来使文本类型的输入元素只接受一个数值(十进制、正数和负数)?
问题描述
我有一个 HTML 输入,这个输入只接受数字字符串,
例子:
输入值:+0123.534534
或 -234234.543345 或-13453
,这些输入值有效。字符 + 或 - 仅存在于字符串值中的第一个位置
我希望每个输入字符输入值都应保留当前有效字符串并用空字符替换无效输入字符
例子:
当我输入:+123.g
==> 值应立即替换+123
。或者当我输入: g ==> 时,该值应立即替换为空值。
我找到了一个实现,但它缺少 (+/-/.) 字符
const getDigitsOnly = (value) => String(value).replace(NOT_NUMBERS, '');
解决方案
从以上评论...
“为什么 OP 不通过像 ... 之类的数字类型输入字段来限制用户输入
<input type="number"/>
?”
“任何
type="text"
基于自定义验证的方法,如果处理得当,都有变得更加复杂的趋势,因为从用户体验的角度来看,即时值清理(在键入或粘贴时)还必须注意重新建立用户最近的插入符号位置。 "
证明上述复杂性...
function stripNeedlessDataFromBoundFieldValue() {
this.value = this.value.replace((/[-+.]$/), '');
}
function getSanitizedValue(value) {
value = value
// remove any leading and trailng whitespace (sequences).
.trim()
// remove any character not equal to minus, plus, dot and digit.
.replace((/[^-+.\d]+/g), '');
if (value.length >= 1) {
let partials = value.split(/(^[+-]?)/);
if (partials.length === 1) {
partials.unshift('');
} else {
partials = partials.slice(1);
}
let [ first, last ] = partials;
last = last.replace((/[+-]+/g), '');
// console.log([ first, last ]);
partials = last.split('.');
if (partials.length === 1) {
partials.unshift('');
} else {
partials = [
partials.shift(),
['.', partials.join('')].join(''),
];
}
first = [first, partials[0]].join('');
last = partials[1];
value = [first, last]
.join('')
.replace(
// trim any sequence of leading zeros into a single one.
(/(^[+-]?)0+/),
(match, sign) => [(sign || ''), 0].join('')
)
.replace(
// always ensure a single zero before a leading sole decimal point.
(/(^[+-]?)\.+/),
(match, sign) => [(sign || ''), '0.'].join('')
);
}
return value;
}
function sanitizeInputValue(evt) {
const elmNode = evt.currentTarget;
const currentValue = elmNode.value;
const sanitizedValue = getSanitizedValue(currentValue);
if (currentValue !== sanitizedValue) {
const diff = sanitizedValue.length - currentValue.length;
const { selectionStart, selectionEnd } = elmNode;
elmNode.value = sanitizedValue;
elmNode.selectionStart =
(selectionStart + diff > 0) ? selectionStart + diff : selectionStart;
elmNode.selectionEnd =
(selectionEnd + diff > 0) ? selectionEnd + diff : selectionEnd;
}
}
function main() {
const textInput = document.querySelector('[type="text"]');
const finalizeBoundFieldValueDebounced = _.debounce(
stripNeedlessDataFromBoundFieldValue.bind(textInput), 1200
);
textInput.addEventListener('input', evt => {
sanitizeInputValue(evt);
finalizeBoundFieldValueDebounced();
});
// // whithout delayed trimming of trailing dot.
//
// document
// .querySelector('[type="text"]')
// .addEventListener('input', sanitizeInputValue);
}
main();
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script>
<input type="text" placeholder="... number only ..."/>
...并将其直接与数字类型字段进行比较...
<input type="number" placeholder="native number type"/>
...以及Micahel Hamami的方法,特此付诸实施...
function sanitizeInputValue({ currentTarget }) {
currentTarget.value = currentTarget.value.replace(/[^0-9,+,-,.]+/g, "");
}
function main() {
document
.querySelector('[type="text"]')
.addEventListener('input', sanitizeInputValue);
}
main();
<input type="text" placeholder="... number only ..."/>
推荐阅读
- javascript - Dynatree“得到无效的加载事件”
- python - 如何减少numpy数组中的行重复次数
- java - 将多个项目和依赖项构建到一个 jar 文件中
- java - 使用 Java 进行极慢的内置 AES 加密
- javascript - 使用 jQuery 修改 classList
- azure-functions - 重放编排时是否应该调用 SetCustomStatus()?
- java - 弹簧数据 jpa 中的 `set @variable = 0` 等价物
- c# - Azure DevOps 发布管道,从 C# 代码中读取环境变量
- c++-winrt - cppwinrt Panel 的子类(或其他类),需要哪些构造函数?
- http - Apache2 自定义标头 - 在标头上添加 Remort 端口