如果输入不是有效数字,则使用<input type=number>
将导致事件侦听器内的this.value
返回空字符串。您可以在http://jsfiddle.net/fSy53/
但是,输入中仍会显示无效字符。
有没有办法从事件监听器中获取实际显示的值,包括无效字符?
我的最终目标是阻止用户在字段中实际输入任何非数字字符。我需要使用type=number
,以便移动设备使用数字虚拟键盘。我的目标是在this.value = this.value.replace(/[^0-9.]/g, "")
上执行keyup keypress
之类的操作,但这不起作用,因为如果输入了无效字符,则从this.value
读取会返回""
。
答案 0 :(得分:59)
如果您不喜欢传入的键值,请尝试阻止默认行为:
document.querySelector("input").addEventListener("keypress", function (evt) {
if (evt.which < 48 || evt.which > 57)
{
evt.preventDefault();
}
});
答案 1 :(得分:21)
您可以通过阻止对非数字值发生keyPress事件来实现此目的
例如(使用jQuery)
$('.input-selector').on('keypress', function(e){
return e.metaKey || // cmd/ctrl
e.which <= 0 || // arrow keys
e.which == 8 || // delete key
/[0-9]/.test(String.fromCharCode(e.which)); // numbers
})
这说明了所有不同类型的输入(例如,数字键盘输入的代码与键盘不同)以及退格键,箭头键,控制/ cmd + r重新加载等
答案 2 :(得分:11)
请注意, e.which , e.keyCode 和 e.charCode 已弃用:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which
我更喜欢 e.key :
document.querySelector("input").addEventListener("keypress", function (e) {
var allowedChars = '0123456789.';
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey = e.key.length === 1 && !contains(allowedChars, e.key)
|| e.key === '.' && contains(e.target.value, '.');
invalidKey && e.preventDefault();});
此功能不会通过检查字符串长度e.key.length === 1
来干扰Firefox中的控制代码( Backspace , Tab 等)。
它还可以防止在开头和数字之间出现重复的点:e.key === '.' && contains(e.target.value, '.')
不幸的是,它不会阻止最后的多个点:234....
似乎无法应对它。
答案 3 :(得分:3)
这个解决方案似乎对我有用。它通过保留ctrl键命令构建在@ pavok的解决方案之上。
document.querySelector("input").addEventListener("keypress", function (e) {
if (
e.key.length === 1 && e.key !== '.' && isNaN(e.key) && !e.ctrlKey ||
e.key === '.' && e.target.value.toString().indexOf('.') > -1
) {
e.preventDefault();
}
});
答案 4 :(得分:2)
inputs[5].addEventListener('keydown', enterNumbers);
function enterNumbers(event) {
if ((event.code == 'ArrowLeft') || (event.code == 'ArrowRight') ||
(event.code == 'ArrowUp') || (event.code == 'ArrowDown') ||
(event.code == 'Delete') || (event.code == 'Backspace')) {
return;
} else if (event.key.search(/\d/) == -1) {
event.preventDefault();
}
}
在这种情况下,当按下非数字按钮时,输入字段的值保持不变,仍然可以正常删除,退格,向上箭头,向下 - 向右工作,并可用于修改数字输入。 / p>
答案 5 :(得分:1)
其他答案似乎比必要的更为复杂,因此我将其答案调整为这种简短而甜美的功能。
function allowOnlyNumbers(event) {
if (event.key.length === 1 && /\D/.test(event.key)) {
event.preventDefault();
}
}
它不会更改任何箭头,输入,Shift,Ctrl或Tab键的行为,因为这些事件的key属性的长度比单个字符长。它还使用简单的正则表达式查找任何非数字字符。
答案 6 :(得分:0)
我也会在使用MacOS的同时添加MetaKey
input.addEventListener("keypress", (e) => {
const key = e.key;
if (!(e.metaKey || e.ctrlKey) && key.length === 1 && !/\d\./.test(key)) {
e.preventDefault();
}
}
或者,您可以尝试!isNaN(parseFloat(key))
答案 7 :(得分:0)
更新接受的答案:
由于许多属性已弃用
(属性)KeyboardEvent。其中:已弃用的数字
您应该仅依靠 key 属性并自行创建其余逻辑:
该代码允许使用Enter,Backspace和所有数字[0-9],不允许其他所有字符。
document.querySelector("input").addEventListener("keypress", (e) => {
if (isNaN(parseInt(e.key, 10)) && e.key !== "Backspace" && e.key !== "Enter") {
e.preventDefault();
}
});
注意 这将禁用粘贴操作
答案 8 :(得分:0)
基于Nrzonline的回答:我解决了多个“”的问题。在输入末尾添加
let lastCharacterEntered
在输入之外,然后在onKeyPress
e => {
var allowedChars = "0123456789.";
function contains(stringValue, charValue) {
return stringValue.indexOf(charValue) > -1;
}
var invalidKey =
(e.key.length === 1 && !contains(allowedChars, e.key)) ||
(e.key === "." && contains(e.target.value, "."));
console.log(e.target.value);
invalidKey && e.preventDefault();
if (!invalidKey) {
if (lastCharacterEntered === "." && e.key === ".") {
e.preventDefault();
} else {
lastCharacterEntered = e.key;
}
}
}
答案 9 :(得分:0)
我只是遇到了同样的问题,并且发现了使用验证API的替代解决方案-在IE之外的所有主要浏览器(Chrome,Firefox,Safari)中都没有黑魔法。该解决方案只是防止用户输入无效值。 我还提供了IE的后备功能,虽然效果不佳,但至少可以正常工作。
上下文:在输入事件上调用 onInput 函数, setInputValue 用于设置输入元素的值, previousInputValue 包含最后一个有效的输入值(在setInputValue调用中更新)。
function onInput (event) {
const inputValue = event.target.value;
// badInput supported on validation api (except IE)
// in IE it will be undefined, so we need strict value check
const badInput = event.target.validity.badInput;
// simply prevent modifying the value
if (badInput === true) {
// it's still possible to enter invalid values in an empty input, so we'll need this trick to prevent that
if (previousInputValue === '') {
setInputValue(' ');
setTimeout(() => {
setInputValue('');
}, 1);
}
return;
}
if (badInput === false) {
setInputValue(inputValue);
return;
}
// fallback case for IE and other abominations
// remove everything from the string expect numbers, point and comma
// replace comma with points (parseFloat works only with points)
let stringVal = String(inputValue)
.replace(/([^0-9.,])/g, '')
.replace(/,/g, '.');
// remove all but first point
const pointIndex = stringVal.indexOf('.');
if (pointIndex !== -1) {
const pointAndBefore = stringVal.substring(0, pointIndex + 1);
const afterPoint = stringVal.substring(pointIndex + 1);
// removing all points after the first
stringVal = `${pointAndBefore}${afterPoint.replace(/\./g, '')}`;
}
const float = parseFloat(stringVal);
if (isNaN(float)) {
// fallback to emptying the input if anything goes south
setInputValue('');
return;
}
setInputValue(stringVal);
}
答案 10 :(得分:-2)
试一试:
document.querySelector("input").addEventListener("keyup", function () {
this.value = this.value.replace(/\D/, "")
});