如何使用更严格的限制自定义 `<input>` 元素

我有一个 html<input>元素,我只想接受数字并在移动设备上将其识别为数字字段。我还希望吞下无效字符,就像标准type=number吞咽不允许的字符一样。

我已经尝试过显而易见的,type=number但它有许多缺点。具体来说,它允许 'e'、'+' 和 '-'(至少在 chrome 中),但这些很容易用一些 JS 修复。真正的问题在于'.' 字符,我希望能够输入浮点数,例如“0.10”、“5.5054”,但不想输入无效的字符串,例如“0.10.1”。我试图通过只允许 1 '.' 来解决这个问题。一次,但这失败了input.value,因为浏览器对它进行了按摩,例如“5”。变为 '5','5..' 变为空(!),并且似乎不可能获得输入中键入的原始字符串值。以上意味着检查现有的 '.' 并采取行动似乎是死胡同......

核心问题:

  1. 有没有办法检查和符合输入?

  2. '有没有一种方法可以将输入标记为一个没有后勤包袱的数字type=number

注意:
* 我意识到你可以粘贴任何你想要的东西,我认为这种行为是病态的,不应该被输入预防所覆盖。

更新

澄清一下,我已经尝试过keypresskeydownetc 事件,但它们还不够,因为我想查看当前输入中存在多少个 '. 以选择是否允许另一个。此时input.value已经被浏览器按摩以删除'.'。我想根据当前输入的 '.' 的数量有条件地允许字符。

例子

HTML(为简洁起见,角度样式绑定)


<input type="number" (keydown)="keyDown()">

JS


function keyDown($event: KeyboardEvent) {

  const inputField = // obtain reference to input element

  const value = inputField.value;

  if ( value.indexOf('.') !== -1 && $event.key === '.') { // disallow another . if one is present

    // ! input field prunes . so this check isn't sufficient

    $event.preventDefault();

    return;

  }


  // This is the crux of the problem e.g.

  // type 5. into input field, value === 5

  // type 5.. into the input field, value === null

  // Since the . char is removed by the input element there's no way to know how many are present!

  console.log(value);

}

概括

有没有办法在<input>不使用type=number属性设置的情况下发出信号类型为 number 的信号。

即移动设备识别和显示数字键盘等

对于一个<input>有type=number没有办法吞下所有不会导致有效数字的键输入

在浏览器将字符添加到输入中之前,不会进行 janky 删除 keyup


繁花不似锦
浏览 178回答 3
3回答

叮当猫咪

一种稍微不同的方法。它允许数字、只有 1 个句点和退格。所有其余的KeyboardEvent.keys 包括ctrl + v和ctrl + c 都被忽略。但是,如果希望允许它们,您可以这样做。为了检查字符是否是10数字之一,我使用的是event.key因为它们可以有两个不同的代码:Digits[0-9]和Numpad[0-9]。但是对于句号和退格,我使用的是event.code因为它们只有一个代码。const input = document.querySelector("#number_input");const App = {&nbsp; isDigit: function(key) {&nbsp; &nbsp; const digits = [&nbsp; &nbsp; &nbsp; "0",&nbsp; &nbsp; &nbsp; "1",&nbsp; &nbsp; &nbsp; "2",&nbsp; &nbsp; &nbsp; "3",&nbsp; &nbsp; &nbsp; "4",&nbsp; &nbsp; &nbsp; "5",&nbsp; &nbsp; &nbsp; "6",&nbsp; &nbsp; &nbsp; "7",&nbsp; &nbsp; &nbsp; "8",&nbsp; &nbsp; &nbsp; "9"&nbsp; &nbsp; ];&nbsp; &nbsp; return digits.includes(key);&nbsp; },&nbsp; isPeriod: function(code) {&nbsp; &nbsp; return code === "Period";&nbsp; },&nbsp; isBackSpace: function(code) {&nbsp; &nbsp; return code === "Backspace";&nbsp; },&nbsp; handleEvent: function(event) {&nbsp; &nbsp; const key = event.key;&nbsp; &nbsp; const code = event.code;&nbsp; &nbsp; const value = input.value;&nbsp; &nbsp; if (App.isDigit(key) || App.isPeriod(code) || App.isBackSpace(code)) {&nbsp; &nbsp; &nbsp; if (App.isPeriod(code) && value.indexOf(key) !== -1) {&nbsp; &nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; }&nbsp; }};input.onkeydown = App.handleEvent<input id="number_input" />一个聪明的黑客由于您坚持使用数字输入。第一次使用,一个虚拟文本输入,您可以使用 CSS 或 Js 隐藏它并验证其值而不是数字输入。const input = document.querySelector("#number_input");const dummyInput = document.querySelector("#dummy_input")const App = {&nbsp; isDigit: function(key) {&nbsp; &nbsp; const digits = [&nbsp; &nbsp; &nbsp; "0",&nbsp; &nbsp; &nbsp; "1",&nbsp; &nbsp; &nbsp; "2",&nbsp; &nbsp; &nbsp; "3",&nbsp; &nbsp; &nbsp; "4",&nbsp; &nbsp; &nbsp; "5",&nbsp; &nbsp; &nbsp; "6",&nbsp; &nbsp; &nbsp; "7",&nbsp; &nbsp; &nbsp; "8",&nbsp; &nbsp; &nbsp; "9"&nbsp; &nbsp; ];&nbsp; &nbsp; return digits.includes(key);&nbsp; },&nbsp; isPeriod: function(code) {&nbsp; &nbsp; return code === "Period";&nbsp; },&nbsp; isBackSpace: function(code) {&nbsp; &nbsp; return code === "Backspace";&nbsp; },&nbsp; handleEvent: function(event) {&nbsp; &nbsp; const key = event.key;&nbsp; &nbsp; const code = event.code;&nbsp; &nbsp; const dummyValue = dummyInput.value;&nbsp; &nbsp; if (App.isBackSpace(code)) {&nbsp; &nbsp; &nbsp; dummyInput.value = dummyValue.substring(0, dummyValue.length - 1)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; if (App.isDigit(key) || App.isPeriod(code)) {&nbsp; &nbsp; &nbsp; &nbsp; if (App.isPeriod(code) && dummyValue.indexOf(key) !== -1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dummyInput.value += event.key&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }};input.onkeydown = App.handleEvent<input type="number" id="number_input" /><input type="text" id="dummy_input" />更新所有使用 input[type="number"] 的答案都有问题。您可以通过鼠标滚轮/微调器将输入值更改为负数。要解决此问题,请为输入设置最小值。<input type="number" min="1" id="number_input" />您需要监听onchange事件,然后更改虚拟输入的值。const input = document.querySelector("#number_input");const dummyInput = document.querySelector("#dummy_input")const App = {&nbsp; isDigit: function(key) {&nbsp; &nbsp; const digits = [&nbsp; &nbsp; &nbsp; "0",&nbsp; &nbsp; &nbsp; "1",&nbsp; &nbsp; &nbsp; "2",&nbsp; &nbsp; &nbsp; "3",&nbsp; &nbsp; &nbsp; "4",&nbsp; &nbsp; &nbsp; "5",&nbsp; &nbsp; &nbsp; "6",&nbsp; &nbsp; &nbsp; "7",&nbsp; &nbsp; &nbsp; "8",&nbsp; &nbsp; &nbsp; "9"&nbsp; &nbsp; ];&nbsp; &nbsp; return digits.includes(key);&nbsp; },&nbsp; isPeriod: function(code) {&nbsp; &nbsp; return code === "Period";&nbsp; },&nbsp; isBackSpace: function(code) {&nbsp; &nbsp; return code === "Backspace";&nbsp; },&nbsp; handleEvent: function(event) {&nbsp; &nbsp; const key = event.key;&nbsp; &nbsp; const code = event.code;&nbsp; &nbsp; const dummyValue = dummyInput.value;&nbsp; &nbsp; if (App.isBackSpace(code)) {&nbsp; &nbsp; &nbsp; dummyInput.value = dummyValue.substring(0, dummyValue.length - 1)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; if (App.isDigit(key) || App.isPeriod(code)) {&nbsp; &nbsp; &nbsp; &nbsp; if (App.isPeriod(code) && dummyValue.indexOf(key) !== -1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dummyInput.value += event.key&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; event.preventDefault();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; },&nbsp; handleChange: function(event) {&nbsp; &nbsp; dummyInput.value = event.target.value&nbsp; }};input.onkeydown = App.handleEvent;input.onchange = App.handleChange;<input type="number" min="1" id="number_input" /><input type="text" id="dummy_input" />

慕斯王

更新答案根据需求变化进行更新。好的,我尝试解决另一个问题,即根据以下代码粘贴您不能粘贴任何内容,您只能粘贴数字,如果您尝试粘贴字符串,输入框将自动变为空:)&nbsp; let special = document.getElementById('inputField');&nbsp; special.addEventListener("keypress", function(e) {&nbsp; let dot = 46;&nbsp; // allowed char: 0-9, .&nbsp; let allow_char = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, dot];&nbsp; if (allow_char.indexOf(e.which) !== -1) {&nbsp; &nbsp; // only 1 dot&nbsp; &nbsp; if (e.which == 46 && special.value.indexOf('.') !== -1)&nbsp; &nbsp; &nbsp; e.preventDefault();&nbsp; } else {&nbsp; &nbsp; e.preventDefault();&nbsp; }});function checkString(){&nbsp; setTimeout(() => {&nbsp; var value = document.getElementById("inputField").value;&nbsp; value = parseInt(value);&nbsp; &nbsp; if(isNaN(value))&nbsp; &nbsp; &nbsp; document.getElementById("inputField").value = "";&nbsp; &nbsp; }, 100);}&nbsp; <input type="number" id="inputField" onpaste="checkString()"/>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java