项目需要能步进小数点的数字输入框,但是mui 的数字输入框只能步进整数,发现只要把 源码中的parseInt 改成 parseFloat 就行了,可是后来新的问题又出现了,浮点数进行加减的精确问题,这是所有编程语言都有的
下面是完美解决方案,只需将mui.js中关于数字输入框的源代码改成如下即可,mui.js中的位置大概在 8158 行左右
/**
* 数字输入框
* varstion 1.0.1
* by Houfeng
* Houfeng@DCloud.io
*/
(function($) {
var touchSupport = ('ontouchstart' in document);
var tapEventName = touchSupport ? 'tap' : 'click';
var changeEventName = 'change';
var holderClassName = 'mui-numbox';
var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
this.floatAdd=function(arg1, arg2){
var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
},
this.floatSub=function(arg1,arg2){
var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}
var _this=this;
var Numbox = $.Numbox = $.Class.extend({
/**
* 构造函数
**/
init: function(holder, options) {
var self = this;
if (!holder) {
throw "构造 numbox 时缺少容器元素";
}
self.holder = holder;
options = options || {};
options.step = parseFloat(options.step || 1);
self.options = options;
self.input = $.qsa(inputClassSelector, self.holder)[0];
self.plus = $.qsa(plusClassSelector, self.holder)[0];
self.minus = $.qsa(minusClassSelector, self.holder)[0];
self.checkValue();
self.initEvent();
},
/**
* 初始化事件绑定
**/
initEvent: function() {
var self = this;
self.plus.addEventListener(tapEventName, function(event) {
// var val = parseFloat(self.input.value) + self.options.step;
var val=_this.floatAdd(parseFloat(self.input.value),self.options.step);
self.input.value = val.toString();
$.trigger(self.input, changeEventName, null);
});
self.minus.addEventListener(tapEventName, function(event) {
// var val = parseFloat(self.input.value) - self.options.step;
var val=_this.floatSub(parseFloat(self.input.value),self.options.step);
self.input.value = val.toString();
$.trigger(self.input, changeEventName, null);
});
self.input.addEventListener(changeEventName, function(event) {
self.checkValue();
var val = parseFloat(self.input.value);
//触发顶层容器
$.trigger(self.holder, changeEventName, {
value: val
});
});
},
/**
* 获取当前值
**/
getValue: function() {
var self = this;
return parseFloat(self.input.value);
},
/**
* 验证当前值是法合法
**/
checkValue: function() {
var self = this;
var val = self.input.value;
if (val == null || val == '' || isNaN(val)) {
self.input.value = self.options.min || 0;
self.minus.disabled = self.options.min != null;
} else {
var val = parseFloat(val);
if (self.options.max != null && !isNaN(self.options.max) && val >= parseFloat(self.options.max)) {
val = self.options.max;
self.plus.disabled = true;
} else {
self.plus.disabled = false;
}
if (self.options.min != null && !isNaN(self.options.min) && val <= parseFloat(self.options.min)) {
val = self.options.min;
self.minus.disabled = true;
} else {
self.minus.disabled = false;
}
self.input.value = val;
}
},
/**
* 更新选项
**/
setOption: function(name, value) {
var self = this;
self.options[name] = value;
},
/**
* 动态设置新值
**/
setValue: function(value) {
this.input.value = value;
this.checkValue();
}
});
$.fn.numbox = function(options) {
var instanceArray = [];
//遍历选择的元素
this.each(function(i, element) {
if (element.numbox) {
return;
}
if (options) {
element.numbox = new Numbox(element, options);
} else {
var optionsText = element.getAttribute('data-numbox-options');
var options = optionsText ? JSON.parse(optionsText) : {};
options.step = element.getAttribute('data-numbox-step') || options.step;
options.min = element.getAttribute('data-numbox-min') || options.min;
options.max = element.getAttribute('data-numbox-max') || options.max;
element.numbox = new Numbox(element, options);
}
});
return this[0] ? this[0].numbox : null;
}
//自动处理 class='mui-locker' 的 dom
$.ready(function() {
$('.' + holderClassName).numbox();
});
}(mui));
强力建议将上面的代码替换到mui.js 源文件的相关处,里面有很多地方需要修改
上效果图:
MUI源码下载
移动端开发框架mui之源代码及 examples 下载
参考资料: