只允许输入数字的HTML文本输入

1109

有没有一种快速的方法可以设置HTML文本输入框(<input type=text />)只允许数字按键(包括 '.')?


102
这里的许多解决方案仅适用于按键输入。如果人们使用菜单粘贴文本,或将文本拖放到文本输入框中,则这些解决方案会失败。我以前就遇到过这种问题。请小心! - Bennett McElwee
103
@JuliusA - 无论如何你始终需要服务器端验证。 - Stephen P
73
<input type="text" onkeypress='return event.charCode >= 48 && event.charCode <= 57'></input> - yurisich
19
请注意,这也会禁用任何其他键,比如TAB键跳转到下一个输入框或者其他与输入无关的快捷键,如当输入框处于聚焦状态时,cmd+R用于刷新网页。 - Alejandro Pérez
1
onkeyup="this.value = this.value.replace(/[^0-9]/g, '');" - ribamar
显示剩余12条评论
80个回答

5

我的解决方案,实现更好的用户体验:

HTML

<input type="tel">

jQuery

$('[type=tel]').on('change', function(e) {
  $(e.target).val($(e.target).val().replace(/[^\d\.]/g, ''))
})
$('[type=tel]').on('keypress', function(e) {
  keys = ['0','1','2','3','4','5','6','7','8','9','.']
  return keys.indexOf(event.key) > -1
})

细节:

首先,输入类型:

number 显示上下箭头,缩小了实际的输入空间,我觉得它们很丑陋,只有在数字表示数量时才有用(像电话、区号、ID等不需要它们) tel 提供了类似于没有箭头的数字的浏览器验证

使用 [number / tel] 还有助于在移动设备上显示数字键盘。

对于 JS 验证,我最终需要了 2 个函数,一个用于正常用户输入(keypress),另一个用于复制+粘贴修复(change),其他组合会给我带来可怕的用户体验。

我使用 更可靠的 KeyboardEvent.key 而不是 现在已弃用的 KeyboardEvent.charCode

根据你的浏览器支持情况,你可以考虑使用 Array.prototype.includes() 替代命名不当的 Array.prototype.indexOf()(用于真 / 假结果)


4

最好的方法(允许所有类型的数字-实数负数,实数正数,整数负数,整数正数)是:

$(input).keypress(function (evt){
    var theEvent = evt || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode( key );
    var regex = /[-\d\.]/; // dowolna liczba (+- ,.) :)
    var objRegex = /^-?\d*[\.]?\d*$/;
    var val = $(evt.target).val();
    if(!regex.test(key) || !objRegex.test(val+key) || 
            !theEvent.keyCode == 46 || !theEvent.keyCode == 8) {
        theEvent.returnValue = false;
        if(theEvent.preventDefault) theEvent.preventDefault();
    };
}); 

4
这是 geowa4 的解决方案 的扩展版本。支持minmax属性。如果数字超出范围,将显示先前的值。 您可以在此处进行测试。 用法:<input type=text class='number' maxlength=3 min=1 max=500>
function number(e) {
var theEvent = e || window.event;
var key = theEvent.keyCode || theEvent.which;
if(key!=13&&key!=9){//allow enter and tab
  key = String.fromCharCode( key );
  var regex = /[0-9]|\./;
  if( !regex.test(key)) {
    theEvent.returnValue = false;
    if(theEvent.preventDefault) theEvent.preventDefault();
    }   
  }
}

$(document).ready(function(){
    $("input[type=text]").filter(".number,.NUMBER").on({
        "focus":function(e){
         $(e.target).data('oldValue',$(e.target).val());
            },
        "keypress":function(e){
                e.target.oldvalue = e.target.value;
                number(e);
            },
        "change":function(e){
            var t = e.target;
            var min = $(t).attr("min");
            var max = $(t).attr("max");
            var val = parseInt($(t).val(),10);          
            if( val<min || max<val)
                {
                    alert("Error!");
                    $(t).val($(t).data('oldValue'));
                }

            }       
    });     
});

如果输入是动态的,请使用以下方法:
$(document).ready(function(){
    $("body").on("focus","input[type=text].number,.NUMBER",function(e){
        $(e.target).data('oldValue',$(e.target).val());
    }); 
    $("body").on("keypress","input[type=text].number,.NUMBER",function(e){
        e.target.oldvalue = e.target.value;
        number(e);
    }); 
    $("body").on("change","input[type=text].number,.NUMBER",function(e){
        var t = e.target
        var min = $(t).attr("min");
        var max = $(t).attr("max");
        var val = parseInt($(t).val());         
        if( val<min || max<val)
            {
                alert("Error!");
                $(t).val($(t).data('oldValue'));
            }
    }); 
});

@UserB 这不应该删除任何东西。 - user669677

3
您可以将Shurok函数替换为:
$(".numeric").keypress(function() {
    return (/[0123456789,.]/.test(String.fromCharCode(Event.which) ))
});

3

使用:

<script>
    function onlyNumber(id){ 
        var DataVal = document.getElementById(id).value;
        document.getElementById(id).value = DataVal.replace(/[^0-9]/g,'');
    }
</script>
<input type="text" id="1" name="1" onChange="onlyNumber(this.id);">

如果你想在按键后更新数值,可以将onChange更改为onKeypressonKeyDownonKeyup。但是需要注意的是,onKeypress事件在某些浏览器中并不会运行。


这个表单是由Javascript + 正则表达式原生创建的。 - Rogerio de Moraes

3

这是一种简单的解决方案

将.price-input input.quantity 替换为您的输入字段的类

$(".price-input input.quantity").on("keypress keyup blur",function (event) {    
       $(this).val($(this).val().replace(/[^\d].+/, ""));
        if ((event.which < 48 || event.which > 57)) {
            event.preventDefault();
        }
    });

谢谢兄弟,让我检查一下。 - Aravind Srinivas
负价格真的吗? - Aravind Srinivas
你的回答可能对提问者来说是正确的。但我个人正在寻找可以涵盖负数的格式。所以不要太在意我上面的评论 :D - Ngoc Nam

3

如果你正在尝试使用Angular,这可能会有所帮助。

要将输入作为数字(含小数点)获取,则

<input [(ngModel)]="data" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');">

现在这样做不会正确更新模型中的值,要显式地更改模型的值,请添加以下内容:

<input [(ngModel)]="data" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" (change)="data = $event.target.value">

改变事件将在模型中的值更新后触发,因此它也可用于响应式表单。


3

下面的代码还将检查PASTE事件。
取消注释“ruleSetArr_4”,并将其添加(连接)到“ruleSetArr”以允许FLOAT数字。
简单的复制/粘贴函数。使用您输入元素作为参数调用它。
示例:inputIntTypeOnly($('input[name="inputName"]'))

function inputIntTypeOnly(elm){
    elm.on("keydown",function(event){
        var e = event || window.event,
            key = e.keyCode || e.which,
            ruleSetArr_1 = [8,9,46], // backspace,tab,delete
            ruleSetArr_2 = [48,49,50,51,52,53,54,55,56,57], // top keyboard num keys
            ruleSetArr_3 = [96,97,98,99,100,101,102,103,104,105], // side keyboard num keys
            ruleSetArr_4 = [17,67,86], // Ctrl & V
          //ruleSetArr_5 = [110,189,190], add this to ruleSetArr to allow float values
            ruleSetArr = ruleSetArr_1.concat(ruleSetArr_2,ruleSetArr_3,ruleSetArr_4); // merge arrays of keys
  
            if(ruleSetArr.indexOf() !== "undefined"){ // check if browser supports indexOf() : IE8 and earlier
                var retRes = ruleSetArr.indexOf(key);
            } else { 
                var retRes = $.inArray(key,ruleSetArr);
            };
            if(retRes == -1){ // if returned key not found in array, return false
                return false;
            } else if(key == 67 || key == 86){ // account for paste events
                event.stopPropagation();
            };

    }).on('paste',function(event){
        var $thisObj = $(this),
            origVal = $thisObj.val(), // orig value
            newVal = event.originalEvent.clipboardData.getData('Text'); // paste clipboard value
        if(newVal.replace(/\D+/g, '') == ""){ // if paste value is not a number, insert orig value and ret false
            $thisObj.val(origVal);
            return false;
        } else {
            $thisObj.val(newVal.replace(/\D+/g, ''));
            return false;
        };
  
    });
};

var inptElm = $('input[name="inputName"]');

inputIntTypeOnly(inptElm);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" name="inputName" value="1">


3

var userName = document.querySelector('#numberField');

userName.addEventListener('input', restrictNumber);
function restrictNumber (e) {  
  var newValue = this.value.replace(new RegExp(/[^\d]/,'ig'), "");
  this.value = newValue;
}
<input type="text" id="numberField">


3
这是我喜欢使用的一个简单好用的解决方案:

以下是示例代码:

function numeric_only (event, input) {
    if ((event.which < 32) || (event.which > 126)) return true; 
    return jQuery.isNumeric ($(input).val () + String.fromCharCode (event.which));
}// numeric_only;

<input type="text" onkeypress="return numeric_only (event, this);" />

解释:

使用"event.which" - 首先确定它是否为可打印字符。如果不是,则允许它(例如删除和退格键)。否则,将字符连接到字符串的末尾并使用jQuery的"isNumeric"函数进行测试。这消除了测试每个单独字符的繁琐过程,并且还适用于剪切/粘贴场景。

如果您想变得更加可爱,那么可以创建一个新的HTML输入类型。我们称之为“numeric”,这样您就可以拥有标签:

<input type="numeric" />

这将只允许数字字符。只需添加以下“document.ready”命令:

$(document).ready (function () {
    $("input[type=numeric]").keypress (function (event) {
        if ((event.which < 32) || (event.which > 126)) return true; 
        return jQuery.isNumeric ($(this).val () + String.fromCharCode (event.which));
    });// numeric.keypress;
});// document.ready;

HTML并不在意你使用的类型名称 - 如果它无法识别,那么它将默认使用文本框,因此你可以这样做。你的编辑器可能会抱怨,但是,嘿,那是它的问题。毫无疑问,有些人会感到恐慌,但它很简单易用,而且到目前为止对我来说非常稳定。

更新

这里有一个更好的方法:考虑了文本选择,并使用本地JavaScript:

verify (event) {
    let value = event.target.value;
    let new_value = `${value.substring (0, event.target.selectionStart)}${event.key}${value.substring (event.target.selectionEnd)}`;
    if ((event.code < 32) || (event.code > 126)) return true;
    if (isNaN (parseInt (new_value))) return false;
    return true;
}// verify;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接