Html 防止在输入类型编号中输入非数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19966417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 15:18:03  来源:igfitidea点击:

Prevent typing non-numeric in input type number

javascripthtml

提问by Explosion Pills

Using <input type=number>will cause this.valueinside of an event listener to return an empty string if the input is not a valid number. You can see an example of this at http://jsfiddle.net/fSy53/

如果输入不是有效数字,则使用<input type=number>将导致this.value事件侦听器内部返回空字符串。你可以在http://jsfiddle.net/fSy53/看到一个例子

However, the invalid characters are still displayed in the input.

但是,无效字符仍然显示在输入中。

Is there any way to get the value that is actually displayed, including the invalid characters, from within an event listener?

有没有办法从事件侦听器中获取实际显示的值,包括无效字符?

My ultimate goal is to prevent users from actually typing any non-numeric characters into the field. I need to use type=numberso that the numeric virtual keyboard is used by mobile devices. My goal would be to do something like this.value = this.value.replace(/[^0-9.]/g, "")on keyup keypress, but this doesn't work because if an invalid character is typed, reading from this.valuereturns "".

我的最终目标是防止用户在字段中实际输入任何非数字字符。我需要使用,type=number以便移动设备使用数字虚拟键盘。我的目标是做这样的事情this.value = this.value.replace(/[^0-9.]/g, "")keyup keypress,但这并不因为如果无效字符键入工作,从阅读this.value的回报""

回答by Glenn Lane

Try preventing the default behaviour if you don't like the incoming key value:

如果您不喜欢传入的键值,请尝试阻止默认行为:

document.querySelector("input").addEventListener("keypress", function (evt) {
    if (evt.which < 48 || evt.which > 57)
    {
        evt.preventDefault();
    }
});

回答by dlangevin

You can accomplish this by preventing the keyPress event from occurring for non-numeric values

您可以通过防止非数字值发生 keyPress 事件来实现此目的

e.g (using jQuery)

例如(使用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
})

This accounts for all different types of input (e.g. input from the number pad has different codes than the keyboard) as well as backspace, arrow keys, control/cmd + r to reload etc

这说明了所有不同类型的输入(例如,从数字键盘输入的代码与键盘的代码不同)以及退格键、箭头键、control/cmd + r 重新加载等

回答by pavok

Please note that e.which, e.keyCodeand e.charCodeare deprecated: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which

请注意e.whiche.keyCodee.charCode已弃用:https: //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which

I prefer e.key:

我更喜欢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();});

This function doesn't interfere with control codes in Firefox (Backspace, Tab, etc) by checking the string length: e.key.length === 1.

该函数不与在Firefox(控制码干扰BackspaceTab通过检查字符串长度,等等): e.key.length === 1

It also prevents duplicate dots at the beginning and between the digits: e.key === '.' && contains(e.target.value, '.')

它还可以防止在开头和数字之间出现重复的点: e.key === '.' && contains(e.target.value, '.')

Unfortunately, it doesn't prevent multiple dots at the end: 234....

不幸的是,它并不能阻止最后出现多个点: 234....

It seems there is no way to cope with it.

似乎没有办法应对。

回答by pigeontoe

This solution seems to be working well for me. It builds on @pavok's solution by preserving ctrl key commands.

这个解决方案似乎对我很有效。它通过保留 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();
  }
});

回答by Fevralle

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();
  }
}

in this case, the value of the input field stays intact when a non-number button is pressed, and still delete, backspace, arrowup-down-left-right work properly and can be used for modifying the digital input.

在这种情况下,按下非数字按钮时,输入字段的值保持不变,并且仍然删除,退格,上下左右箭头正常工作,可用于修改数字输入。

回答by KenCorbettJr

The other answers seemed more complicated than necessary so I adapted their answers to this short and sweet function.

其他答案似乎比必要的更复杂,因此我将他们的答案调整为这个简短而甜蜜的功能。

function allowOnlyNumbers(event) {
  if (event.key.length === 1 && /\D/.test(event.key)) {
    event.preventDefault();
  }
}

It won't do change the behavior of any arrow, enter, shift, ctrl or tab keys because the length of the key property for those events is longer than a single character. It also uses a simple regular expressions to look for any non digit character.

它不会改变任何箭头、回车、移位、ctrl 或 tab 键的行为,因为这些事件的键属性的长度比单个字符长。它还使用简单的正则表达式来查找任何非数字字符。

回答by Eugen Sunic

Update on the accepted answer:

更新已接受的答案:

Because of many properties becoming deprecated

由于许多属性已被弃用

(property) KeyboardEvent.which: number @deprecated

(属性)KeyboardEvent.which:数字@deprecated

you should just rely on the keyproperty and create the rest of the logic by yourself:

您应该只依赖于key属性并自己创建其余的逻辑:

The code allows Enter, Backspace and all numbers [0-9], every other character is disallowed.

该代码允许 Enter、Backspace 和所有数字 [0-9],不允许使用其他任何字符。

document.querySelector("input").addEventListener("keypress", (e) => {
  if (isNaN(parseInt(e.key, 10)) && e.key !== "Backspace" && e.key !== "Enter") {
      e.preventDefault();
    }
});

NOTEThis will disable paste action

注意这将禁用粘贴操作

回答by Chajia

Based on Nrzonline's answer: I fixed the problem of the multiple "." at the end of the input by adding a

基于 Nrzonline 的回答:我解决了多个“.”的问题。在输入的末尾添加一个

let lastCharacterEntered

outside of the input and then onKeyPress

在输入之外然后 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;
            }
          }
        }

回答by ábel énekes

I just had the same problem and discovered an alternative solution using the validation API - works without black magic in all major browsers (Chrome, Firefox, Safari) except IE. This solution simply prevents users from entering invalid values. I also included a fallback for IE, which is not nice but works at least.

我刚刚遇到了同样的问题,并发现了使用验证 API 的替代解决方案 - 在除 IE 之外的所有主要浏览器(Chrome、Firefox、Safari)中都没有黑魔法。此解决方案只是防止用户输入无效值。我还包括了 IE 的后备,这不是很好,但至少有效。

Context: onInputfunction is called on input events, setInputValueis used to set the value of the input element, previousInputValuecontains the last valid input value (updated in setInputValue calls).

上下文: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);
}

回答by Polv

I will add MetaKey as well, as I am using MacOS

我也会添加 MetaKey,因为我使用的是 MacOS

input.addEventListener("keypress", (e) => {
    const key = e.key;
    if (!(e.metaKey || e.ctrlKey) && key.length === 1 && !/\d\./.test(key)) {
        e.preventDefault();
    }
}

Or, you can try !isNaN(parseFloat(key))

或者,你可以试试 !isNaN(parseFloat(key))