如何只允许在输入[type =“number”]字段中输入数字?

时间:2017-09-28 13:08:25

标签: javascript html input

我有一个输入字段,用户只能输入数字[0-9]

document.getElementById("integer").addEventListener('input', restrictToInteger);
function restrictToInteger() {
    this.value = this.value.replace(/[^\d]/g, '');
}
<input type="number" id="integer" />

jsFiddle Demo

问题是这样的:当我输入一个数字(例如1234)然后按点(.),+或 - 时,浏览器会自动删除输入字段的内容( value设置为“”=空字符串)。但为什么?将类型从number更改为text似乎可以解决问题。但后来我失去了输入字段的向上/向下箭头功能。有什么想法吗?

9 个答案:

答案 0 :(得分:4)

我认为浏览器清理输入值的原因是因为带有两个点的字符串不是数字。

对您的代码进行了一些更正:

如果要接受带小数部分的数字,则需要定期更改表达式。现在,你只是表示你想接受数字[0-9]而不是更多的字符。

要完成您想要的任务,您需要将/[^\d]/g更改为/[^\d.]/g

&#13;
&#13;
document.getElementById("integer").addEventListener('input', restrictToInteger);

function restrictToInteger()
{
  this.value = this.value.replace(/[^\d.]/g, '');
}
&#13;
<input type="number" id="integer" />
&#13;
&#13;
&#13;

HOWEVER:如果您将输入定义为数字类型,则不需要正则表达式。所以,您只需要像这样定义输入,并且应该根据您的情况定义:

&#13;
&#13;
<input type="number" id="integer" />
&#13;
&#13;
&#13;

[解决方案]

为了完全满足您的需求,我提供了一个解决方案,可以捕获输入的keydown事件,并检查是否有任何&#39;。&#39;在输入上。如果是,我会阻止char转到输入。

&#13;
&#13;
document.getElementById("integer").addEventListener('keydown', restrictToInteger);
var lastCodeWasDot = false;
function restrictToInteger(e)
{
   var inputValue = document.getElementById("integer").value;
   var isDot = false;
   var isDot = (e.keyCode && e.keyCode == 110) || (e.charCode && e.charCode == 190);
   console.log(e.keyCode);
   if(isDot && (inputValue.indexOf(".") > -1 || inputValue == "" || lastCodeWasDot)) {
       e.preventDefault();
   }
   lastCodeWasDot = isDot;
   
}
&#13;
<input type="number" id="integer" />
&#13;
&#13;
&#13;

解释解决方案

需要代码行var isDot = (e.keyCode && e.keyCode == 110) || (e.charCode && e.keyCode == 190) || false;,因为跨浏览器兼容性

我现在不知道为什么但是如果你试图从firefox中的输入数字类型中获取值,并且如果值以点结束,那么你将获得的值将没有最后一个点输入。要解决这个问题,我需要添加变量lastCodeWasDot来解决此问题。

  

注意:数字输入可以接受浮点数,包括负号和e或E字符(查看this帖子)

答案 1 :(得分:2)

根据Alexandru-Ionut Mihainatchiketa的答案,我创建了以下解决方案:

document.getElementById("integer").addEventListener("input", allowOnlyDigits);

function allowOnlyDigits() {  
  if (this.validity.valid) {
    this.setAttribute('current-value', this.value.replace(/[^\d]/g, ""));
  }
  this.value = this.getAttribute('current-value');
}
<input type="number" id="integer" />

输入时,检查值的有效性。如果它有效,则删除所有非数字,并将值存储在元素的自定义属性中。如果该值无效,则恢复先前的值。

备注:

  • 只有Internet Explorer才需要RegEx-replace,因为它允许您在数字末尾输入,.
  • 在IE,Edge,Chrome和Firefox中测试
  • Chrome仍允许您输入+之前和,之后的数字。
  • 我发现了一个问题:如果使用值初始化字段,那么当您第一次点击键盘上的无效字符时,该值就会丢失。
  • 另一个问题:您无法输入负数。

答案 2 :(得分:2)

HTML 4具有一个名为onkeypress事件。有了该属性,我们无需使用其他JS就可以做到这一点:

<input type="number" onkeypress="return (event.charCode == 8 || event.charCode == 0 || event.charCode == 13) ? null : event.charCode >= 48 && event.charCode <= 57">

09的{​​{1}}允许从event.charCode48的数字。

答案 3 :(得分:1)

唯一的问题是你的输入类型。将其更改为text,它应该有效!

function validate(e) {
    var charCode = e.keyCode? e.keyCode : e.charCode
    if (!(charCode >= 48 && charCode <= 57)) {
        if(!(charCode>=37 && charCode<=40))
            if(charCode!=8 && charCode!=46)
            return false;
    }
}
<input type="number" id="integer" pattern="[0-9]"
onkeydown="return validate(event)"/>

答案 4 :(得分:1)

您可以通过copying输入的值来实现您的要求,并使用setAttributegetAttribute方法来存储值。

&#13;
&#13;
function myFunction(input){
  input.setAttribute('current-value',"");
  input.oninput=function(){  
      let currentValue=input.getAttribute('current-value');
      if(input.value!='' || (currentValue>=1 && currentValue<=9))
        input.setAttribute('current-value',input.value);
      input.value=input.getAttribute('current-value');
  }
}
&#13;
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
<input type="number" oninput="myFunction(this)"/>
&#13;
&#13;
&#13;

答案 5 :(得分:1)

我会切换到cancelable之类的keydown事件 这样你就可以防止首先输入字符:

var cancelEvent = function (e) {
    e.preventDefault();
    return false;
},
restrictToInteger = function restrictToInteger(e) {
    var acceptableInput = /[0-9]/g,
        clipboardKeys = /[zxcv]/ig,
        field = e.key || e.char,
      isClipboardOperation = (clipboardKeys.test(field) && e.ctrlKey),
        inputIsAcceptable = field ? (
            acceptableInput.test(field)
            || field.length > 1
            || isClipboardOperation
        ) : true;

    if (!inputIsAcceptable) {
        cancelEvent(e);
    }
},
ensureIntegerValueOnPaste = function ensureIntegerValueOnPaste(e) {
	var data = e.clipboardData || e.dataTransfer,
  		text = data.getData('text'),
        int = parseInt(this.value + text, 10);

    if (isNaN(int)) {
        cancelEvent(e);
    } else {
        window.setTimeout(function () {
            e.target.value = int;
        }, 0);
    }
},
input = document.getElementById("integer");

input.addEventListener('keydown', restrictToInteger);
input.addEventListener('drop', ensureIntegerValueOnPaste);
input.addEventListener('paste', ensureIntegerValueOnPaste);
<input type="number" id="integer" />

更新了小提琴:https://jsfiddle.net/838pa8hv/2/

免责声明:

  • 仅在Chrome中测试过。
  • field.length > 1的测试是捕获有效的非数字键,因为向上/向下箭头的值分别为ArrowUpArrowDown。这也允许按下Shift(或HomeBackspaceDelete等键。)

修改: 要处理粘贴(和丢弃),您可以在相应的事件中执行相同的操作。 Updated fiddle以及上面的代码段。

修改
如果预期的可用性是能够将部分数字粘贴/删除到字段以不允许负整数,那么您只需更改intensureIntegerValueOnPaste中的定义方式功能。 Updated fiddle以及上面的代码段。

答案 6 :(得分:1)

当您致电oninput时,<input>元素首先调用其内部方法来处理该值。这可以防止您的函数看到任何实际的错误字符,即e+-. - 所有这些都被JavaScript用来格式化数字。

您可以在更改console.log之前和之后添加this.value来电来查看此内容。

console.log(this.value);
this.value=this.value.replace(/[^\d]/g, '');
console.log(this.value);

没有任何区别!

如果您尝试,例如:

console.log(this.value);
this.value+=1; // or *=2 for numerical fun
console.log(this.value);

你可以看到差异。

所以你的函数正在加速处理非法输入时正常的内部调用<input type='number'/>

不能完全理解为什么该字段留空而不是1

答案 7 :(得分:0)

您不需要正则表达式,可以使用parseFloat()函数。您的输入类型保持不变,仍然有“箭头”来增加/减少数字,并确保您的输入不会从零开始。

document.getElementById("integer").addEventListener('input', restrictToInteger);
function restrictToInteger() {
  this.value = parseFloat(this.value);
}
<input type="number" id="integer" />

答案 8 :(得分:0)

您必须检查该值是否不是数字,然后停止用户。

&#13;
&#13;
document.getElementById("integer").addEventListener('input', restrictToInteger);

function restrictToInteger(e)
{
  if(isNaN(e.data)){
     alert("only numbers allowed");
  }
}
&#13;
<input type="number" id="integer" />
&#13;
&#13;
&#13;