fake-progress库的源码如下:
var FakeProgress = function (opts) {
if (!opts) { opts = {}; }
this.timeConstant = opts.timeConstant || 1000;
this.autoStart = opts.autoStart || false;
this.parent = opts.parent;
this.parentStart = opts.parentStart;
this.parentEnd = opts.parentEnd;
this.progress = 0;
this._intervalFrequency = 100;
this._running = false;
if (this.autoStart) {
this.start();
}
}
FakeProgress.prototype.start = function () {
this._time = 0;
this._intervalId = setInterval(this._onInterval.bind(this), this._intervalFrequency);
};
FakeProgress.prototype._onInterval = function () {
this._time += this._intervalFrequency;
this.setProgress(1 - Math.exp((-1 * this._time) / this.timeConstant));
};
FakeProgress.prototype.end = function () {
this.stop();
this.setProgress(1);
};
FakeProgress.prototype.stop = function () {
clearInterval(this._intervalId);
this._intervalId = null;
};
FakeProgress.prototype.createSubProgress = function (opts) {
var parentStart = opts.start || this.progress;
var parentEnd = opts.end || 1;
var options = Object.assign({}, opts, {
parent: this,
parentStart: parentStart,
parentEnd: parentEnd,
start: null,
end: null
});
var subProgress = new FakeProgress(options);
return subProgress;
};
FakeProgress.prototype.setProgress = function (progress) {
this.progress = progress;
if (this.parent) { this.parent.setProgress((this.parentEnd - this.parentStart) * this.progress + this.parentStart); }
};
我们需要核心关注的参数只有timeConstant,autoStart这两个参数,通过阅读源码可以知道timeConstant相当于分母,分母越大则加的越少,而autoStart则是一个开关,如果开启了直接执行start方法,开启累计的定时器。通过这个库,我们实现一个虚拟的进度条,永远到达不了100%的进度条。
调用如下:
var fake = new FakeProgress({
timeConstant: 1000,
autoStart: true
});
Object.defineProperties(fake, { progress: {
get: function () {
return progress;
},
set: function (val) {
progress = val;
var _proNum = parseInt(progress * 100);
if (_proNum >= 99) {
clearInterval(this._intervalId);
this._intervalId = null;
}
$('#_progressBarBulletbox').progressbar('setValue', _proNum);
}
}
});
function pageLoadBarDownFile(progressBarId) {
progressBarId = progressBarId || "_progressBarBulletbox";
var _width = $(window).width() / 2;
var html = "<div id=\"" + progressBarId + "\" class=\"easyui-progressbar\" data-options=\"value:0\" style=\"width:" + _width + "px;\"></div>";
$("<div class=\"datagrid-mask\"></div>").css({ display: "block", width: "100%", height: $(window).height() }).appendTo("body");
$(html).appendTo("body").css({ display: "block", height: '10%', width: '50%', position: 'fixed', top: 0, right: 0, bottom: 0, left: 0, margin: 'auto', left: 0 });
}
如果需要实现一个永远不满的进度条,那么你可以借助fake-progress核心是1 - Math.exp((-1 * this._time) / this.timeConstant) 这个公式
涉及到一个数据公式: e的负无穷次方 趋近于0。所以1-e^-x永远到不了1,但趋近于1
核心原理就是:用时间做分子,传入的timeConstant做分母,通过Math.exp((-1 * this._time) / this.timeConstant) 可知,如果时间不断累积且为负值,那么Math.exp((-1 * this._time) / this.timeConstant) 就无限趋近于0。所以1 - Math.exp((-1 * this._time) / this.timeConstant) 就可以得到无限趋近于1 的值。