在做考试系统的时候遇到一个问题,就是在汇总成绩的时候可能会出现汇总时间过程,导致用户不知道是否汇总完还是服务器卡死的问题,所以给了给用户更好的体验,决定加一个进度条显示。
这里写一个简单的demo:
<style>
#divProgress{width:300px;height:24px;position:relative;}
#divProgress div{position:absolute;left:0;top:0;height:24px;}
#progressBg{background-color:#B9F8F9;z-index:10;}
#progressText{z-index:15;text-align:center;width:100%;}
</style>
</head>
<body>
<div id="divProgress">
<div id="progressBg"></div>
<div id="progressText"></div>
</div>
<br />
<button οnclick="send()">提交数据</button>
<script>
var t =document.getElementById("progressText");
var bg =document.getElementById("progressBg");
function send(){
t.innerHTML = "loading";
bg.style.width = "0px";
var xhr = newwindow.XMLHttpRequest();
if(!window.XMLHttpRequest){
try {
xhr = newwindow.ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {}
}
xhr.open("post","http://localhost:8080/testLoading/chunk.jsp?count=6");
varoldSize=0;
xhr.onreadystatechange = function(){
if(xhr.readyState> 2){
vartmpText = xhr.responseText.substring(oldSize);
oldSize =xhr.responseText.length;
if(tmpText.length> 0 ){
// 设置文本
t.innerHTML = tmpText + "/100";
// 设置进度条
var width= parseInt(tmpText)/100*300;
bg.style.width = width+"px";
}
}
if(xhr.readyState== 4){
// 请求执行完毕
t.innerHTML = "执行完毕";
bg.style.width = "300px";
}
}
xhr.send(null);
}
</script>
</body>
通过另一个页来控制显示:
<body>
<%
// 下面设置Content-Type:application/x-javascript是为了适应Webkit的浏览器(chrome,safari)
response.setHeader("Content-Type","application/x-javascript");
int count= 100; // 处理6条数据
for(inti=0;i<count;i++){
// 处理完毕一条,输出结果到客户端
out.println(i+1);
out.flush();
// 这里假设每条数据处理时间为1秒
Thread.currentThread().sleep(100);
}
%>
</body>
这里用的java语句来写,但是,如何适应我们现在做的项目呢?
首先分析一下汇总成绩实现的过程:
首先,需要或许需要汇总成绩的成绩表。
其次,需要汇总表中符合条件的成绩。
再次,把汇总好的数据更新成绩表。
最后,更新考试表的汇总字段。
所以,我们需要在适当的时候提示用户当前正在进行的步骤。
所以,在struts中action代码如下:
PrintWriter out =ServletActionContext.getResponse().getWriter();
request.setAttribute("importExam", StudentCount_combox_exam);
// 下面设置Content-Type:application/x-javascript是为了适应Webkit的浏览器(chrome,safari)
response.setHeader("Content-Type","application/x-javascript");
String examId = request.getParameter("examID");
out.print("正在获取成绩表...");
out.flush();
Thread.currentThread().sleep(100);
List<String> scoreTableList = droplistService.QueryScoreTable(examId);
int count = 10;
for(int i=0;i<count;i++){
// 处理完毕一条,输出结果到客户端
out.print(i+1);
out.flush();
// 这里假设每条数据处理时间为0.1秒
Thread.currentThread().sleep(100);
}
out.print("正在计算学生成绩...");
out.flush();
Thread.currentThread().sleep(2000);
List stuScoreList =droplistService.queryCountStuScore(scoreTableList);
for(int i=11;i<50;i++){
// 处理完毕一条,输出结果到客户端
out.print(i+1);
out.flush();
// 这里假设每条数据处理时间为0.1秒
Thread.currentThread().sleep(100);
}
out.print("正在更新学生成绩...");
out.flush();
Thread.currentThread().sleep(4000);
droplistService.updateStuSore(stuScoreList);
for(int i=51;i<90;i++){
// 处理完毕一条,输出结果到客户端
out.print(i+1);
out.flush();
// 这里假设每条数据处理时间为0.1秒
Thread.currentThread().sleep(100);
}
out.print("正在更改考核状态...");
out.flush();
Thread.currentThread().sleep(2000);
droplistService.updateExamTypeByExamId(examId);
count = 100;
for(int i=91;i<100;i++){
// 处理完毕一条,输出结果到客户端
out.print(i+1);
out.flush();
// 这里假设每条数据处理时间为0.1秒
Thread.currentThread().sleep(100);
}
最后,看一下效果图:
这样,用户就可以清楚的看到当前后台正在执行哪一步了,虽然对于程序来说计算时间是一样的,但是对于用户体验来说,完全不一样了。