JavaScript模拟实现进度条

                  JavaScript模拟实现进度条

需求描述: 客户端excel导入大量数据,服务器处理起来比较慢,且服务器无法返回当前文件的处理进度(此处进度可以理解为服务器已处理的数据条数/上传总条数 ),这时如若服务器处理过慢,一直不给客户端响应,而客户端也没有相关变化的情况下,会导致用户体验及其不好。
解决方案: 客户端自己实现一个假进度条,当上传开始后显示一个进度条给用户。
实现细节: 
       1、发起请求。
       2、显示进度条,进度条前进百分比初始化为0;
       3、产生随机数进度条前进的百分比和所需时间随机数(根据参数产生);
       4、如果进度条到达成功前可以前进最大值(此时请求还没有响应,最大值根据参数),卡死进度条,等待响应。
       5、收到服务器响应,请求成功,无论进度条在何位置,均在0.3s内走完进度条,调用成功的回调。
       6、请求失败, 调用失败的回调。
源码: 
  /*
 * version 1.1.0
 假进度条:

  实现服务器处理数据的假进度:
  当达到某个值之后,若服务器还没有处理完,则停止进度条前进,待服务器处理完之后,结束进度条。
  若进度条还没有走完,服务器就已经完成处理,加速走完进度条
  参数说明:带*为必须参数
调用实例:
var process=new ProcessedAjax({
                url: "url",
                type: "get",
                okCallback: function(data){
                   alert("成功了");
                    console.log(data);
                    process.destroy();
                },
                errorCallback: function(data){
                    alert("失败了")
                    console.log(data);
                }
            });
 1.url(*)
  发起请求的url
 2.type(默认post)
  请求类型
 3.data(默认{})
  参数
 4.okCallback ()
  成功的回调
 5.errorCallback()
  失败的回调
 6.backColor(默认#eee)
  自定义进度条默认颜色
 7.processColor(默认#009ed8)
  自定义进度颜色
 8.stillTime(单位S,默认3)
  进度条时间
 9.stepTime(单位S,默认.3)
  每走一步的间隔时间
 10.stepNum(默认10%)0-100之间
  每走一步的进度百分比
 11.container
  装进度条的容器
 12:deadline(默认90%)0-100之间
  进度条卡死百分比
 13:duringTime
  进度条走一步的动画时间
 依赖说明: 依赖jquery
 * */
function ProcessedAjax(option) {
try {
var _this = this.__proto__;
if(!option.url) {
console.error("url不能为空");
return;
}
if(option.type && option.type.indexOf(_this.ALLOW_AJAX_TYPE) < 0) {
console.log("ajax类型不允许");
return;
};
console.log(_this)
option = _this.arguPrevHandle(option);
_this.settings = $.extend({}, _this.DEFAULT_ARGU, option);
_this.sendToServer();
return {
start: _this.sendToServer,
destroy: _this.destroy
}
} catch(e) {
console.log("运行时发生了错误:" + e.message);
}
}


//默认参数
ProcessedAjax.prototype.DEFAULT_ARGU = {
type: "post",
data: {},
okCallback: function(data) {},
errorCallback: function(data) {},
backColor: "#eee",
processColor: "#009ed8",
stillTime: 3,
stepTime: .3,
stepNum: 10,
deadline: 90,
duringTime: .3
}


//允许的ajax类型
ProcessedAjax.prototype.ALLOW_AJAX_TYPE = ["get", "post", "delete", "put"];


//传入参数预处理
ProcessedAjax.prototype.arguPrevHandle = function(option) {
option.okCallback = (option.okCallback instanceof Function) ? option.okCallback : undefined;
option.errorCallback = (option.errorCallback instanceof Function) ? option.errorCallback : undefined;
option.stillTime = isNaN(parseFloat(option.stillTime)) ? undefined : parseFloat(option.stillTime);
option.stepTime = isNaN(parseFloat(option.stepTime)) ? undefined : parseFloat(option.stepTime);
option.stepNum = isNaN(parseFloat(option.stepNum)) ? undefined :
(parseFloat(option.stepNum) > 100 ? 100 : parseFloat(option.stepNum) < 0 ? 0 : parseFloat(option.stepNum));
option.deadline = isNaN(parseFloat(option.deadline)) ? undefined :
(parseFloat(option.deadline) > 100 ? 100 : parseFloat(option.deadline) < 0 ? 0 : parseFloat(option.deadline));
option.duringTime = isNaN(parseFloat(option.duringTime)) ? undefined : parseFloat(option.duringTime);
return option;
}


//发送请求
ProcessedAjax.prototype.sendToServer = function() {
//$.ajaxBase(this.settings.type, this.settings.url, this.settings.data, this.successCallback.bind(this), this.defaultCallback.bind(this));
$.ajax({
type: this.settings.type,
url: this.settings.url,
data: this.settings.data,
dataType: "json",
error: this.successCallback.bind(this),
success: this.defaultCallback.bind(this),
async:true
});
this.showProcess();
this.setProcessInterval();
}


//显示进度条
ProcessedAjax.prototype.showProcess = function() {
$(".process-percent").remove();
var processDom =
"<div class='process-percent'>" +
" <div class='process-percent-back'></div>" +
" <div class='process-percent-ok' data-percent='0'></div>" +
"</div>";
if($(this.settings.container).length > 0) {
$(this.settings.container).append(processDom);
} else {
$("body").append(processDom);
}
this.percent = 0;
}


//销毁
ProcessedAjax.prototype.destroy = function() {
setTimeout(function(){
$(".process-percent").remove();
},600);
$(".process-percent").css({
"opacity": "0",
"transition": 'opacity .5s linear'
});
clearInterval(this.processInterval);
this.processInterval = null;
if(this.unrealDeadProcessInterval) {
clearInterval(this.unrealDeadProcessInterval);
this.unrealDeadProcessInterval=null;
}
}


//进度条改变定时器
ProcessedAjax.prototype.setProcessInterval = function() {
this.processInterval = setInterval(function() {
this.forwardProcess();
}.bind(this), this.settings.stepTime * 1000);
//随机假死进度条
this.unrealDeadProcess();
}


//进度条前进
ProcessedAjax.prototype.forwardProcess = function() {
//进度条前进的百分比大于等于成功前的最大百分比,卡死进度条
if(parseFloat(this.percent) >= parseFloat(this.settings.deadline)
|| (parseFloat(this.percent) + parseFloat(this.settings.stepNum)) >= parseFloat(this.settings.deadline)) {
this.deadProcess();
return;
}
this.setProcessPercent(parseFloat(this.settings.stepNum),.1);
}


//设置进度条百分比
ProcessedAjax.prototype.setProcessPercent = function(percent, time) {
this.percent=parseFloat(this.percent)+parseFloat(percent);
this.percent=parseFloat(this.percent)>100?100:parseFloat(this.percent);
$(".process-percent .process-percent-ok").attr("data-percent",this.percent);
var allWidth = $(".process-percent .process-percent-back").outerWidth(true);
$(".process-percent .process-percent-ok").css({
width: allWidth * (this.percent / 100),
transition: "width " + time + "s" + " linear"
});
}


//卡死进度条
ProcessedAjax.prototype.deadProcess = function(isError) {
clearInterval(this.processInterval);
this.processInterval = null;
if(isError) {//保证因为失败引起的卡死不会重启定时器
if(this.unrealDeadProcessInterval) {
clearInterval(this.unrealDeadProcessInterval);
this.unrealDeadProcessInterval=null;
}
}
}


无论如何走完进度条
ProcessedAjax.prototype.processToAllAnyway = function() {
this.setProcessPercent(100,.3);
}


//随机假死进度条,假死时间1-10s随机
ProcessedAjax.prototype.unrealDeadProcess = function() {
this.unrealDeadProcessInterval = setInterval(function() {
if(this.percent === 0) {


} else {
this.deadProcess();
clearInterval(this.unrealDeadProcessInterval);
this.unrealDeadProcessInterval=null;
this.reuseProcessInterval();
}
}.bind(this), this.getRandomNum(1,10)*1000);
}


//重启进度条前进定时器,前进百分比随机
ProcessedAjax.prototype.reuseProcessInterval = function() {
var addPercent=this.getRandomNum(0,100-parseFloat(this.percent));
this.setProcessPercent(addPercent, .3);
this.setProcessInterval();
}


//产生变化随机数
ProcessedAjax.prototype.getRandomNum = function(min,max) {
var numArea = max - min;//大小范围
var rand = Math.random();//随机数
return(min + Math.round(rand * numArea));
}


//成功的回调
ProcessedAjax.prototype.successCallback = function(data) {
this.processToAllAnyway();
setTimeout(function(){
this.settings.okCallback(data);
}.bind(this),500);


}


//失败的回调
ProcessedAjax.prototype.defaultCallback = function(data) {
this.deadProcess(true);
this.settings.errorCallback(data);
}


/*
个人原创,技术有限,不喜勿喷!
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值