如何使用jQuery在HTML输入框中只允许输入数字(0-9)?

981

我正在创建一个网页,其中有一个输入文本框,我想只允许输入数字字符,例如 (0,1,2,3,4,5...9) 0-9。

使用jQuery如何实现这个功能?


79
请记住,您不能仅依赖客户端验证 - 您还需要在服务器上进行验证,以防用户关闭了JavaScript或未使用兼容JavaScript的浏览器。 - cjk
50
你考虑过使用 HTML5 吗?<input type="number" />。通过使用最小值和最大值属性,你可以限制输入的范围。 - ZX12R
6
我认为你应该在输入按键松开事件(keyup event)时检查输入值,而不是检查按键代码(keycodes),因为这样可以更可靠地处理不同键盘等因素所带来的差异。 - Richard
14
我完全赞同Richard的意见:不要使用按键码。接受的答案在法语键盘上无法正常工作,例如,在这些键盘上输入数字需要按下“Shift”键。依我看,按键码太过冒险。 - MiniQuark
3
@ZX12R这段代码在所有的IE浏览器中都无法使用。尽管在自己的项目中使用最新的代码可能会让人感到新鲜,但对于几乎任何专业项目来说,这并不是一个真正的选择。 http://caniuse.com/#feat=input-number - Eric
显示剩余14条评论
68个回答

1361

注意: 这是一个更新的答案。下面的评论是针对旧版本的,该版本会搞乱按键码。

jQuery

在 JSFiddle 上试一试 on JSFiddle.

目前没有原生的 jQuery 实现方法,但您可以使用以下的 inputFilter 插件来过滤文本输入框的输入值(支持复制+粘贴、拖放、键盘快捷键、上下文菜单操作、不可输入的键、插入符位置、不同的键盘布局、有效性错误消息和 自 IE 9 以来的所有浏览器):

// Restricts input for the set of matched elements to the given inputFilter function.
(function($) {
  $.fn.inputFilter = function(callback, errMsg) {
    return this.on("input keydown keyup mousedown mouseup select contextmenu drop focusout", function(e) {
      if (callback(this.value)) {
        // Accepted value
        if (["keydown","mousedown","focusout"].indexOf(e.type) >= 0){
          $(this).removeClass("input-error");
          this.setCustomValidity("");
        }
        this.oldValue = this.value;
        this.oldSelectionStart = this.selectionStart;
        this.oldSelectionEnd = this.selectionEnd;
      } else if (this.hasOwnProperty("oldValue")) {
        // Rejected value - restore the previous one
        $(this).addClass("input-error");
        this.setCustomValidity(errMsg);
        this.reportValidity();
        this.value = this.oldValue;
        this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
      } else {
        // Rejected value - nothing to restore
        this.value = "";
      }
    });
  };
}(jQuery));

现在您可以使用inputFilter插件来安装输入过滤器:
$(document).ready(function() {
  $("#myTextBox").inputFilter(function(value) {
    return /^\d*$/.test(value);    // Allow digits only, using a RegExp
  },"Only digits allowed");
});

将您喜欢的样式应用于输入错误类。以下是建议:

.input-error{
  outline: 1px solid red;
}

请看JSFiddle演示以获取更多输入过滤示例。同时请注意,您仍然必须进行服务器端验证!

纯JavaScript(无jQuery)

实际上不需要jQuery,您也可以使用纯JavaScript来完成相同的事情。请参见此答案

HTML 5

HTML 5具有本地解决方案,即<input type="number">(请参见规范),但请注意,浏览器支持程度各异:

  • 大多数浏览器只有在提交表单时才会验证输入,而不是在键入时。
  • 大多数移动浏览器不支持stepminmax属性。
  • Chrome(版本71.0.3578.98)仍允许用户在字段中输入字符eE。请参见此问题
  • Firefox(版本64.0)和Edge(EdgeHTML版本17.17134)仍允许用户在字段中输入任何文本。

请在 w3schools.com 上自行尝试on


47
感谢您的选择! 事件.keyCode == 46 || 事件.keyCode == 8 || 事件.keyCode == 190 如果想要输入小数。 - Michael L Watson
9
为了允许在文本框中进行左右箭头导航,请添加键码37和39。例如:如果(event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39)。 - Anthony Queen
22
刚刚我们的测试人员发现了一个问题。你需要防止用户长按Shift键并按数字键,否则输入将会包含 !@#$%^&*() 这些字符。 - Allen Rice
6
确认了shift+键的错误。另外,ALT+数字键盘几乎可以输入任何内容(例如,Alt+321 = A,Alt+322 = B等)。这是服务器端验证的另一个案例。 - Anthony Queen
149
我非常不同意这个答案:使用按键码非常危险,因为你无法确定键盘布局。例如,在法语键盘上,用户必须按 Shift 键才能输入数字。因此,这段代码根本不起作用。所以请使用验证而不是这种按键码技巧。 - MiniQuark
显示剩余21条评论

200

这是我使用的函数:

// Numeric only control handler
jQuery.fn.ForceNumericOnly =
function()
{
    return this.each(function()
    {
        $(this).keydown(function(e)
        {
            var key = e.charCode || e.keyCode || 0;
            // allow backspace, tab, delete, enter, arrows, numbers and keypad numbers ONLY
            // home, end, period, and numpad decimal
            return (
                key == 8 || 
                key == 9 ||
                key == 13 ||
                key == 46 ||
                key == 110 ||
                key == 190 ||
                (key >= 35 && key <= 40) ||
                (key >= 48 && key <= 57) ||
                (key >= 96 && key <= 105));
        });
    });
};
你可以通过以下方式将它连接到你的控件上:

You can then attach it to your control by doing:


$("#yourTextBoxName").ForceNumericOnly();

2
我发现这很有用,但是我发现一个烦人的“bug”。当我在我的iMac上使用它时,它允许一些字母,比如a和e。似乎PC上的键盘数字在iMac上是字母,而Mac键盘与常规数字相同。有人知道如何使它在Mac和PC上都能正常工作吗? - Volmar
3
"Home"和"End"键也无法使用。这是Peter建议的更好解决方案:http://www.west-wind.com/weblog/posts/2011/Apr/22/Restricting-Input-in-HTML-Textboxes-to-Numeric-Values。 - bman
2
@powtac - 这样你就可以在多个对象上调用 .ForceNumericOnly()。例如... $("input[type='text']").ForceNumericOnly() - Oliver Pearmain
1
@powtac,“return this.each(function()”中的“each”是为了允许多个对象,正如HaggleLad所说的那样,“return”部分是将jQuery对象返回给调用者,以允许链接,例如“$("input[type='text'").ForceNumericOnly().show()”。 - Jose Rui Santos
请美化一下,但是请添加 key == 13 || 来确保允许按回车键提交表单等操作。 - Pawel Cioch
显示剩余5条评论

180

内联:

<input name="number" onkeyup="if (/\D/g.test(this.value)) this.value = this.value.replace(/\D/g,'')">

不显眼的样式(使用jQuery):

$('input[name="number"]').keyup(function(e)
                                {
  if (/\D/g.test(this.value))
  {
    // Filter non-digits from input value.
    this.value = this.value.replace(/\D/g, '');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="number">


2
即使用户按下左箭头键,这也会将插入符号移动到末尾。 - Phrogz
1
@phrogz,试试这个:onkeyup="if (/\D/g.test(this.value)) this.value = this.value.replace(/\D/g,'')" - Patrick Fisher
1
至少在Chrome 24上,这会导致非数字出现,然后立即被删除,看起来相当低劣(与一开始就防止非数字输入相比)。 - mhenry1384
6
那是预期的行为。我认为这是不错的反馈,但如果你不喜欢,那么采用密钥代码的方法就是你要找的。 - Patrick Fisher
2
你可以修改为/[^0-9]|^0+(?!$)/g以防止前导零的连续出现。 - Johny Skovdal
显示剩余8条评论

108

您可以像这样使用输入事件:

$(document).on("input", ".numeric", function() {
    this.value = this.value.replace(/\D/g,'');
});

但是,什么是代码特权?

  • 它适用于移动浏览器(keydown和keyCode存在问题)。
  • 它也适用于由AJAX生成的内容,因为我们使用了"on"。
  • 比如在粘贴事件上,性能更好。

8
我觉得这个解决方案比被采纳的答案更加健壮(且简单)。 - Jeremy Harris
如果使用replace(/\D/g, ''),甚至更简单。 - Alfergon
你好,我该如何确保一个数值是介于 0.024.0 之间的十进制数?我无法让它输入小数点 . - Transformer
1
我建议使用 this.value = Number(this.value.replace(/\D/g, '')); - HasanG
好的答案,允许通过切换类轻松地切换输入是否为数字。 - raklos

107
你可以使用简单的JavaScript正则表达式测试是否为纯数字字符:
/^[0-9]+$/.test(input);

如果输入是数字,返回true;否则返回false。

对于事件按键码,只需使用以下代码:

     // Allow: backspace, delete, tab, escape, enter, ctrl+A and .
    if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
         // Allow: Ctrl+A
        (e.keyCode == 65 && e.ctrlKey === true) || 
         // Allow: home, end, left, right
        (e.keyCode >= 35 && e.keyCode <= 39)) {
             // let it happen, don't do anything
             return;
    }

    var charValue = String.fromCharCode(e.keyCode)
        , valid = /^[0-9]+$/.test(charValue);

    if (!valid) {
        e.preventDefault();
    }

11
请看我对这种方法的实现的答案。 - Patrick Fisher
检查数字按键是否比检查正则表达式需要更少的处理器时间? - andrsnn
这不会阻止使用CTRL+V粘贴字母对吧? - Laurens Swart

71

简短而精炼 - 即使在30多个回答之后,这也不会引起太多注意 ;)

  $('#number_only').bind('keyup paste', function(){
        this.value = this.value.replace(/[^0-9]/g, '');
  });

7
我会把keyup替换成input,否则你可能会一直按住某个键,然后单击以使焦点离开文本框,这样会让文本保持原状。使用input可以确保这种情况不会发生。 - WizLiz
3
感谢提供正则表达式,但是这个事件处理程序更好一些:$('#number_only').on('input propertychange', function(){this.value = this.value.replace(/[^0-9]/g, '');});它可以确保输入框只能输入数字。 - BradM
6
FYI - 这个问题没有要求,但不允许使用小数(例如12.75)。绑定“input”而不是“keyup”可以使用户体验更加顺畅,而不是看到他们的字符瞬间出现然后被删除。 - Paul

45

使用JavaScript函数isNaN

if (isNaN($('#inputid').val()))

if (isNaN(document.getElementById('inputid').val()))

如果(document.getElementById('inputid').val())不是数字,那么执行下面的代码。
if (isNaN(document.getElementById('inputid').value))

更新: 这里有一篇不错的文章介绍了如何使用jQuery实现此功能:限制HTML文本框中的输入为数字值


41
好的,“不使用JQuery”,除了你的示例中使用JQuery的部分之外......” - GalacticCowboy
document.getElementById('inputid').val() 这还是 jQuery 的东西。使用 .value - mpen
12
仅使用isNaN是不好的,因为会涉及到JavaScript类型转换。 - josh3736
你好,我该如何确保一个数值是介于 0.024.0 之间的十进制数?我无法让它输入小数点 . - Transformer

34
$(document).ready(function() {
    $("#txtboxToFilter").keydown(function(event) {
        // Allow only backspace and delete
        if ( event.keyCode == 46 || event.keyCode == 8 ) {
            // let it happen, don't do anything
        }
        else {
            // Ensure that it is a number and stop the keypress
            if (event.keyCode < 48 || event.keyCode > 57 ) {
                event.preventDefault(); 
            }   
        }
    });
});

来源: http://snipt.net/GerryEng/jquery-making-textfield-only-accept-numeric-values

该代码使用jQuery和JavaScript来限制文本字段仅接受数字输入。它将捕获键盘输入事件并根据按下的键是否为数字或控制字符(如删除、Tab等)来决定是否允许输入。同时,它还可以过滤粘贴的内容以确保它们只包含数字。

7
哇,空的“if”代码块和魔法数字都在使用!我有点恶心了。但是说真的,为什么要费这么大劲呢?你只需将输入与正则表达式 /^[.\d]+$/ 进行匹配即可。而“8”代表什么意思呢? - Alan Moore
@Alan:哈哈,我也不知道——我是直接从源代码复制的。我会写成“if(event.keyCode != 46 && event.keyCode != 8)”或者像你说的那样使用正则表达式。我想8代表删除键。 - Ivar
4
尝试按Shift + 8键-您的验证将允许 * 符号进入。 - Anton
这很不错。如果它能处理Shift键+数字(特殊字符如!@#$ %^..),那就更好了。 - Shyju

31

我在我们内部的公用JS文件中使用此代码。 我只需将此类添加到需要此行为的任何输入中即可。

$(".numericOnly").keypress(function (e) {
    if (String.fromCharCode(e.keyCode).match(/[^0-9]/g)) return false;
});

3
好的,代码很漂亮、优雅且实用!谢谢。但是你必须添加keyup和keydown事件。 - Silvio Delgado

26

为什么要这么复杂呢?因为有HTML5的pattern属性,所以您甚至不需要jQuery:

<input type="text" pattern="[0-9]*">

很赞的一点是它在移动设备上会弹出数字键盘,比使用jQuery方便得多。


2
这个应该有更多的投票。如果需要,您还可以为非HTML5浏览器添加回退正则表达式 - 但数据验证无论如何都应该在服务器端处理。 - Markus
现在大多数浏览器都支持得很好,所以现代浏览器的支持已经不那么重要了:http://caniuse.com/#search=pattern 即使 Safari 在该网站上被列为部分支持,但它的表现非常出色。试试吧! - guest
@guest 非常感谢您。最快、最简单的答案!在我看来是最好的答案。 - BinaryJoe01

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