首页 文章

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

提问于
浏览
10

我有一个输入字段,用户应该只能输入数字 [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 )然后按点( . ),或者 - 浏览器自动删除输入字段的内容(值设置为“”=空字符串) . 但为什么?将类型从 number 更改为 text 似乎可以解决问题 . 但后来我失去了输入字段的向上/向下箭头功能 . 有任何想法吗?

8 回答

  • 0

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

    Some corrections about your code:

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

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

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

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

    <input type="number" id="integer" />
    

    [THE SOLUTION]

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

    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;
       
    }
    
    <input type="number" id="integer" />
    

    解释解决方案:

    代码行 var isDot = (e.keyCode && e.keyCode == 110) || (e.charCode && e.keyCode == 190) || false; 是必需的,因为 cross browser compatibility .

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

    注意:数字输入可以接受浮点数,包括负号和e或E字符(查看这篇文章)

  • 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" />
    

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

    Notes:

    • 仅对Internet Explorer需要RegEx替换,因为它允许您在数字的末尾输入 ,. .

    • 在IE,Edge,Chrome和Firefox中测试过

    • Chrome仍允许您输入 + 之前和 , 之后输入数字 .

    • 我发现了一个问题:如果使用值初始化字段,则在第一次点击键盘上的无效字符时,该值将丢失 .

    • 另一个问题:您无法输入负数 .

  • 0

    唯一的问题是你的输入类型 . 将其更改为 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)"/>
    
  • 1

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

    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');
      }
    }
    
    <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)"/>
    
  • 4

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

    您可以通过在更改 this.value 之前和之后添加 console.log 调用来查看此内容 .

    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 .

  • 1

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

    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 等)键 .

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

    Edit
    如果预期的可用性是能够将部分数字粘贴/删除到字段 and 以不允许负整数,那么您只需更改 ensureIntegerValueOnPaste 函数中定义 int 的方式 . Updated fiddle和上面的代码片段 .

  • 1

    你不需要正则表达式,你可以使用 parseFloat() 函数 . 您的输入类型保持不变,仍有"arrows"增加/减少数字,并确保您的输入不会以零开头 .

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

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

    document.getElementById("integer").addEventListener('input', restrictToInteger);
    
    function restrictToInteger(e)
    {
      if(isNaN(e.data)){
         alert("only numbers allowed");
      }
    }
    
    <input type="number" id="integer" />
    

相关问题