【问题标题】:Knockout - restrict input to only numbers with one decimal point淘汰赛 - 将输入限制为仅带一位小数的数字
【发布时间】:2014-12-21 07:48:28
【问题描述】:

我有下面的代码,它确实将输入限制为仅数字和选择数量的组合键。但我也想限制输入只接受一个小数点。

number: {
            init: function (element) {
                // Allows only numbers with decimals
                $(element).on("keydown", function (event) {
                    // Allow: backspace, delete, tab, escape, and enter
                    if (event.keyCode === 46 || event.keyCode === 8 || event.keyCode === 9 || event.keyCode === 27 || event.keyCode === 13 ||
                        // Allow: Ctrl+A, Ctrl + C, Ctrl + V, Ctrl + X
                        ((event.keyCode === 65 || event.keyCode === 67 || event.keyCode === 86 || event.keyCode === 88) && (event.ctrlKey === true || event.metaKey === true)) ||
                        // Allow: .
                        (event.keyCode === 190 || event.keyCode === 110) ||
                        // Allow: home, end, left, right
                        (event.keyCode >= 35 && event.keyCode <= 39)) {
                        // let it happen, don't do anything
                        return;
                    } else {
                        // Ensure that it is a number and stop the keypress
                        if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                            event.preventDefault();
                        }
                    }
                });
            }
        }

我尝试像下面那样添加'$(element).val().indexOf('.') !== -1',但它没有做任何事情,我仍然可以输入我想要的多个句点。我应该如何实际限制它?

if (event.shiftKey || ($(element).val().indexOf('.') !== -1 && (event.keyCode === 190 || event.keyCode === 110)) || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                event.preventDefault();
                        }

【问题讨论】:

  • ...然后我过来将“lorem ipsum”粘贴到输入中。 :-)
  • @T.J.Crowder 没想到哈哈..

标签: javascript forms knockout.js


【解决方案1】:

所以我必须说我并没有真正看到明确允许的逻辑;相反,您应该明确排除,因为默认情况下所有内容都是允许的。你买了一台电脑,它通过了你的所有标准,你不会买 10 台电脑,然后扔掉那些不符合你标准的电脑。因此,无需触摸 Ctrl 和其他功能键,您将其变得不必要地复杂。
如果您仔细查看您极长的if 子句,您会注意到以下内容:
(event.keyCode === 190,您在其中声明了// let it happen, don't do anything。因此,无论如何都会添加句​​点。以下是您当前方法的问题:

  • keydown 事件中,所有键码都会产生相同的,而Caps Lock 是否打开,因为它们是相同的。所以你无法区分句号.和分号;
  • 对于keydown 事件,数字键盘和键盘上相同数字的键码不同,因为它们是不同的
  • 禁用 Shift 键(如您所做的那样)会强制 AZERTY 用户使用 Caps Lock,因为 AZERTY 键盘在 Shift 关闭时会生成非数字字符。

因此,您最好使用返回字符值keypress 事件。这是一个重构的更简洁的函数,它实现了完全相同的效果:

 $('#jquery').on("keypress", function (event) {
   var k = event.keyCode || event.charCode;
   if (k === 46 && this.value.match(/\./g) || (k < 48 && k !== 46 ) || k > 57) {                            
     event.preventDefault();
   }
 });

在这里测试:http://jsfiddle.net/kevinvanlierde/5ay3cory/6/

注意:由于 Mozilla Firefox 不擅长区分 keydown 和 keypress,因此它也会混淆并禁用所有控制键。

【讨论】:

  • 这不符合我的目的。仅当您将句点作为第一个字符输入时它才能正常工作,而当您在任何其他字符之后输入时则不能正常工作。
【解决方案2】:
if ((yourString.match(new RegExp(".", "g")) || []).length > 1) {
  // yourString contains more than one "."
}

【讨论】:

    【解决方案3】:

    我修复了自己的代码,并想在这里分享:

    // Allows only numbers with decimals
    $(element).on("keydown", function(event) {
        // Allow: backspace, delete, tab, escape, and enter
        if (event.keyCode === 46 || event.keyCode === 8 || event.keyCode === 9 || event.keyCode === 27 || event.keyCode === 13 ||
            // Allow: Ctrl+A
            (event.keyCode === 65 && (event.ctrlKey === true || event.metaKey === true)) ||
            // Allow: .
            (event.keyCode === 190 || event.keyCode === 110) ||
            // Allow: home, end, left, right
            (event.keyCode >= 35 && event.keyCode <= 39)) {
            // let it happen, but check for excessive periods
            if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
                event.preventDefault();
            }
            return;
        } else {
            // Ensure that it is a number and stop the keypress
            if (event.shiftKey || (event.keyCode < 48 || event.keyCode > 57) && (event.keyCode < 96 || event.keyCode > 105)) {
                event.preventDefault();
            }
        }
    });
    

    我在允许某些键码的地方添加了以下代码:

    if ((event.keyCode === 190 || event.keyCode === 110) && $(element).val().indexOf('.') !== -1) {
        event.preventDefault();
    }
    

    【讨论】:

    • 有人可能会说这样更好。但是,我已经修复了我的代码,它现在和这个一样好,而且更好,因为它不会通过禁用 Shift 来损害 AZERTY 键盘用户。 (参见jsfiddle.net/kevinvanlierde/5ay3cory/6,在 Chrome、Opera、Mozilla FF、IE 上进行了测试)。不过,您自己的答案和我的答案都对 Firefox 存在问题:您的代码不允许使用句号,而我的代码不允许控制键(因为 Firefox 在实现键盘标准方面很糟糕)。
    猜你喜欢
    • 2013-06-07
    • 2013-04-10
    • 2014-10-21
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多