80

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

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

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

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

4

12 回答 12

90

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

document.querySelector("input").addEventListener("keypress", function (evt) {
    if (evt.which < 48 || evt.which > 57)
    {
        evt.preventDefault();
    }
});
于 2013-11-13T23:30:36.823 回答
23

您可以通过防止非数字值发生 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 重新加载等

于 2014-12-04T16:43:44.193 回答
17

请注意e.whiche.keyCodee.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();});

通过检查字符串长度,此函数不会干扰 Firefox( 、 等)中的控制Backspace代码Tabe.key.length === 1

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

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

似乎没有办法应付它。

于 2017-03-15T09:54:44.323 回答
6

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

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

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

于 2019-08-21T19:28:44.920 回答
3
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();
  }
}

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

于 2017-06-03T20:11:30.510 回答
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();
  }
});
于 2018-04-11T16:38:28.170 回答
0

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

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

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

于 2019-04-04T18:59:27.627 回答
0

更新接受的答案:

由于许多属性已被弃用

(属性)KeyboardEvent.which: number @deprecated

您应该只依赖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();
    }
});

注意 这将禁用粘贴操作

于 2019-08-23T07:15:11.090 回答
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;
            }
          }
        }
于 2020-03-25T10:00:13.740 回答
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);
}
于 2020-05-06T08:22:21.943 回答
0

防止在具有多个输入项的页面的特定输入 id 中键入非字母。它可用于 Oracle Apex 开发人员 --- 附加在页面的 HTML 标题中

<script type="text/javascript">
function validateNumber(event) {
  const activeElmnt = document.activeElement;  
  var keyCode = event.keyCode;
  var excludedKeys = [8, 37, 39, 46];
 
   if ( activeElmnt.id == "input id in HTML page"){
        if (!((keyCode >= 65 && keyCode <= 90) ||
            (keyCode >= 97 && keyCode <= 122) ||
            (excludedKeys.includes(keyCode)))) {
            console.log("alphabets are not allowed");
            event.preventDefault();

  }
}
  console.log("keycode: " + keyCode + "ActiveElemet: "+activeElmnt.id);
}
</script>

-- 附加在页面 HTML Body 属性 onkeydown="validateNumber(event);"

于 2021-09-13T06:43:41.663 回答
-2

尝试一下:

document.querySelector("input").addEventListener("keyup", function () {
   this.value = this.value.replace(/\D/, "")
});
于 2013-11-13T23:26:55.693 回答