MUI中小数点的数字输入框,步进step为小数时的需求和浮点数的精确问题

项目需要能步进小数点的数字输入框,但是mui 的数字输入框只能步进整数,发现只要把 源码中的parseInt 改成 parseFloat 就行了,可是后来新的问题又出现了,

浮点数进行加减的精确问题,这是所有编程语言都有的.

下面是完美解决方案,只需将mui.js中关于数字输入框的源代码改成如下即可,mui.js中的位置大概在8158行左右

  1 /**
  2  * 数字输入框
  3  * varstion 1.0.1
  4  * by Houfeng
  5  * Houfeng@DCloud.io
  6  */
  7  
  8 (function($) {
  9  
 10     var touchSupport = ('ontouchstart' in document);
 11     var tapEventName = touchSupport ? 'tap' : 'click';
 12     var changeEventName = 'change';
 13     var holderClassName = 'mui-numbox';
 14     var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
 15     var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
 16     var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
 17  
 18     
 19     this.floatAdd=function(arg1, arg2){
 20              var r1, r2, m, c;
 21             try {
 22                 r1 = arg1.toString().split(".")[1].length;
 23             }
 24             catch (e) {
 25                 r1 = 0;
 26             }
 27             try {
 28                 r2 = arg2.toString().split(".")[1].length;
 29             }
 30             catch (e) {
 31                 r2 = 0;
 32             }
 33             c = Math.abs(r1 - r2);
 34             m = Math.pow(10, Math.max(r1, r2));
 35             if (c > 0) {
 36                 var cm = Math.pow(10, c);
 37                 if (r1 > r2) {
 38                     arg1 = Number(arg1.toString().replace(".", ""));
 39                     arg2 = Number(arg2.toString().replace(".", "")) * cm;
 40                 } else {
 41                     arg1 = Number(arg1.toString().replace(".", "")) * cm;
 42                     arg2 = Number(arg2.toString().replace(".", ""));
 43                 }
 44             } else {
 45                 arg1 = Number(arg1.toString().replace(".", ""));
 46                 arg2 = Number(arg2.toString().replace(".", ""));
 47             }
 48             return (arg1 + arg2) / m;
 49         },
 50         this.floatSub=function(arg1,arg2){
 51             var r1, r2, m, n;
 52             try {
 53                 r1 = arg1.toString().split(".")[1].length;
 54             }
 55             catch (e) {
 56                 r1 = 0;
 57             }
 58             try {
 59                 r2 = arg2.toString().split(".")[1].length;
 60             }
 61             catch (e) {
 62                 r2 = 0;
 63             }
 64             m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
 65             n = (r1 >= r2) ? r1 : r2;
 66             return ((arg1 * m - arg2 * m) / m).toFixed(n);
 67         }
 68  
 69     var _this=this;
 70     var Numbox = $.Numbox = $.Class.extend({
 71         /**
 72          * 构造函数
 73          **/
 74         init: function(holder, options) {
 75             var self = this;
 76             if (!holder) {
 77                 throw "构造 numbox 时缺少容器元素";
 78             }
 79             self.holder = holder;
 80             options = options || {};
 81             options.step = parseFloat(options.step || 1);
 82             self.options = options;
 83             self.input = $.qsa(inputClassSelector, self.holder)[0];
 84             self.plus = $.qsa(plusClassSelector, self.holder)[0];
 85             self.minus = $.qsa(minusClassSelector, self.holder)[0];
 86             self.checkValue();
 87             self.initEvent();
 88         },
 89         /**
 90          * 初始化事件绑定
 91          **/
 92         initEvent: function() {
 93             var self = this;
 94             self.plus.addEventListener(tapEventName, function(event) {
 95 //              var val = parseFloat(self.input.value) + self.options.step;
 96                 var val=_this.floatAdd(parseFloat(self.input.value),self.options.step);
 97                 self.input.value = val.toString();
 98                 $.trigger(self.input, changeEventName, null);
 99             });
100             self.minus.addEventListener(tapEventName, function(event) {
101 //              var val = parseFloat(self.input.value) - self.options.step;
102                 var val=_this.floatSub(parseFloat(self.input.value),self.options.step);
103                 self.input.value = val.toString();
104                 $.trigger(self.input, changeEventName, null);
105             });
106             self.input.addEventListener(changeEventName, function(event) {
107                 self.checkValue();
108                 var val = parseFloat(self.input.value);
109                 //触发顶层容器
110                 $.trigger(self.holder, changeEventName, {
111                     value: val
112                 });
113             });
114         },
115         /**
116          * 获取当前值
117          **/
118         getValue: function() {
119             var self = this;
120             return parseFloat(self.input.value);
121         },
122         /**
123          * 验证当前值是法合法
124          **/
125         checkValue: function() {
126             var self = this;
127             var val = self.input.value;
128             if (val == null || val == '' || isNaN(val)) {
129                 self.input.value = self.options.min || 0;
130                 self.minus.disabled = self.options.min != null;
131             } else {
132                 var val = parseFloat(val);
133                 if (self.options.max != null && !isNaN(self.options.max) && val >= parseFloat(self.options.max)) {
134                     val = self.options.max;
135                     self.plus.disabled = true;
136                 } else {
137                     self.plus.disabled = false;
138                 }
139                 if (self.options.min != null && !isNaN(self.options.min) && val <= parseFloat(self.options.min)) {
140                     val = self.options.min;
141                     self.minus.disabled = true;
142                 } else {
143                     self.minus.disabled = false;
144                 }
145                 self.input.value = val;
146             }
147         },
148         /**
149          * 更新选项
150          **/
151         setOption: function(name, value) {
152             var self = this;
153             self.options[name] = value;
154         },
155         /**
156          * 动态设置新值
157          **/
158         setValue: function(value) {
159             this.input.value = value;
160             this.checkValue();
161         }
162         
163     });
164  
165     $.fn.numbox = function(options) {
166         var instanceArray = [];
167         //遍历选择的元素
168         this.each(function(i, element) {
169             if (element.numbox) {
170                 return;
171             }
172             if (options) {
173                 element.numbox = new Numbox(element, options);
174             } else {
175                 var optionsText = element.getAttribute('data-numbox-options');
176                 var options = optionsText ? JSON.parse(optionsText) : {};
177                 options.step = element.getAttribute('data-numbox-step') || options.step;
178                 options.min = element.getAttribute('data-numbox-min') || options.min;
179                 options.max = element.getAttribute('data-numbox-max') || options.max;
180                 element.numbox = new Numbox(element, options);
181             }
182         });
183         return this[0] ? this[0].numbox : null;
184     }
185  
186     //自动处理 class='mui-locker' 的 dom
187     $.ready(function() {
188         $('.' + holderClassName).numbox();
189     });
190  
191 }(mui));
原文地址:https://www.cnblogs.com/lgx5/p/14696395.html