4

我正在尝试编写一个 jQuery 插件来防止用户输入超过 2 位小数的数字。具体来说:

  • 如果输入包含12并且用户3最后键入,它应该可以工作。
  • 如果输入包含12.34并且用户1最后键入,则什么都不会发生
  • 如果输入包含12.34并且用户1在开始时键入,它应该可以工作。

这是我遇到的问题:

  • 如果我绑定到keypress,我不知道“提议的新值”是什么;$(this).val()是用户按下键之前的值,我不知道用户在输入字段中输入的位置。
  • 如果我绑定到keyup,$(this).val()是新值,但它已经出现在文本输入中。如果它有太多小数位,我可以删除它,但它看起来有问题。

我怎样才能做到这一点?

4

2 回答 2

3

美比这个?

jQuery.fn.limitDecimalPlaces = function(maxPlaces) {
  $(this).on('keyup', function(e) {
    integer = e.target.value.split('.')[0],
    mantissa = e.target.value.split('.')[1];

    if (typeof mantissa === 'undefined') {
      mantissa = '';
    }

    if (mantissa.length > maxPlaces) {
      e.target.value = integer + '.' + mantissa.substring(0, maxPlaces);
    }
  });
}

在http://jsfiddle.net/vdZfH/2/测试和工作

于 2012-06-14T20:55:31.383 回答
2

适合我的目的的解决方案

这就是我想出的。

优点

  • 多余的小数位根本不出现(与出现并立即被删除相反)
  • 用户也不能输入多个小数

缺点

此解决方案依赖于其中的 2 个其他 jQuery 插件,但无论如何我已经在我的项目中拥有它们。

  • 我正在使用作为caret()一部分的函数jQuery.maskedInput来确定用户在输入框中输入的位置。
  • 我已经在这个输入上使用了,jQuery.keyfilter以确保只允许输入它。(不过,它只考虑单个击键,而不考虑结果输入内容。)1-9.

编码

jQuery.fn.limitDecimalPlaces = function (maxPlacesArg) {
  $(this).each(function() {
    var maxPlaces, presetValue;

    if (maxPlacesArg) {
      maxPlaces = maxPlacesArg;

    } else {
      presetValue = $(this).attr('value');

      // If the value attribute has a decimal in it...
      if (presetValue.indexOf('.') !== -1) {

        // ... assume it has the correct number of places
        maxPlaces = presetValue.split('.')[1].length;
      } else {

        // Sensible default
        maxPlaces = 2;
      }
    }
    $(this).bind("keypress", function(e) {
      var currentVal, cursorIsAfterDecimal, hasMaxDecimalPlaces, inputHasDecimal, keystrokeIsDecimal;
      currentVal = $(this).val();
      inputHasDecimal = currentVal.indexOf('.') !== -1;
      if (inputHasDecimal) {
        // Booleans
        keystrokeIsDecimal = String.fromCharCode(e.which) === '.';
        hasMaxDecimalPlaces = athena.format.hasNDecimalPlaces(currentVal, maxPlaces);
        cursorIsAfterDecimal = ($(this).caret().begin) > (currentVal.lastIndexOf('.'));

        if (keystrokeIsDecimal || (hasMaxDecimalPlaces && cursorIsAfterDecimal)) {
          e.preventDefault();
        }
      }
    });
  });
  return $(this);
}

配套功能:

hasNDecimalPlaces = function (number, places) {
  fixed = parseFloat(number).toFixed(places);
  return number.toString() === fixed;
};
于 2012-06-14T20:45:21.277 回答