`
bjtale
  • 浏览: 28826 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Ajax实现页面自动刷新与进度条制作

阅读更多

     在实际Web页面中,有一些数据是需要实时反馈给浏览者的,但是完全刷新当前页面从而改变页面部分内容将会是很不友好的用户体验,并且浏览者也不容易发现哪些数据或内容是重新加载的。此时,使用Ajax技术定时向服务器发送改变页面内容请求,从而即可实现页面内容自动刷新的效果。

      以下实例通过一个按钮点击事件来出发页面自动刷新效果,通常在实际开发中会使用onload事件取代。js代码中较多地使用了setTimeout()方法来定时执行特定的函数,通过响应信息的内容对DOM对象进行动态修改。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
var xhr;
function createXhr(){
	if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
		xhr=new XMLHttpRequest();
	} else {// code for IE6, IE5
		xhr=new ActiveXObject("Microsoft.XMLHTTP");
	}
}
function getStart(){
	createXhr();
	var url = "AutoRefresh?task=reset";
	xhr.open("GET",url,true);
	xhr.onreadystatechange = doCallback;
	xhr.send(null);
}
function doCallback(){
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			setTimeout("respServer()", 5000);
			refreshTime();
		}
	}
}
function respServer(){
	createXhr();
	var url = "AutoRefresh?task=ref";
	xhr.open("GET",url,true);
	xhr.onreadystatechange = refCallback;
	xhr.send(null);
}
function refCallback(){
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			var message = xhr.responseXML.getElementsByTagName("message")[0].firstChild.data;
			if(message != "done"){
				var new_row = createRow(message);
				var table = document.getElementById("tab");
				var t_body = table.getElementsByTagName("tbody").item(0);
				var first_row = t_body.getElementsByTagName("tr").item(1);
				t_body.insertBefore(new_row, first_row);
				setTimeout("respServer()", 5000);
				refreshTime();
			}
		}
	}
}
function refreshTime(){
	var time_span = document.getElementById("time");
	var time_val = time_span.innerHTML;
	var int_val = parseInt(time_val);
	var new_val = int_val - 1;
	if(new_val > 0 ){
		setTimeout("refreshTime()", 1000);
		time_span.innerHTML = new_val;
	} else {
		time_span.innerHTML = 5;
	}
}
function createRow(message){
	var row = document.createElement("tr");
	var cell = document.createElement("td");
	var data = document.createTextNode(message);
	cell.appendChild(data);
	row.appendChild(cell);
	return row;
}
</script>
</head>
<body>
	<h2>Auto fresh page</h2>
	<input type="button" value="start" onclick="getStart();">
	<p>
		Page will refresh in <span id="time">5</span> seconds.
	</p> 
	<table id="tab" align="left">
		<tbody>
			<tr><td></td></tr>
		</tbody>
	</table>
</body>
</html>

      服务端代码较为简洁,仅仅是通过计数器的变化返回一些不同的信息。最终响应信息将使用XML格式进行传输,客户端需要将XML处理为DOM对象进行解析。

package com.any.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class AutoRefresh
 */
@WebServlet("/AutoRefresh")
public class AutoRefresh extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private int counter = 1;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public AutoRefresh() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String res = "";
		String task = request.getParameter("task");
		String message = "";
		
		if(task.equals("reset")){
			counter = 1;
		} else {
			switch(counter){
			case 1:message="message 1";break;
			case 2:message="message 2";break;
			case 3:message="message 3";break;
			case 4:message="message 4";break;
			case 5:message="message 5";break;
			case 6:message="message 6";break;
			case 7:message="done";break;
			}
			counter++;
		}
		res = "<message>"+message+"</message>";
		response.setContentType("text/xml");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		out.println("<response>");
		out.println(res);
		out.println("</response>");
		out.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

}

      启动并进入当前页面后,点击start按钮即可发现页面在自动读取响应信息,并将信息展示在当前页面,整个页面也没有进行重新绘制。

     

      另外,在实际应用中,我们会经常遇到开发一个进度条的情况。通常的做法是选择插件,本文将不依赖于任何插件,通过Ajax技术每隔1.5秒向服务器发送一次数据请求,返回当前任务进度,从而展示在页面上。客户端仅需要根据服务端返回任务进度数据的第一位来控制进度条中进度块的着色即可。

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
var xhr;
var key;
var bar_color = 'gray';
var span_id="block";
var clear = "&nbsp;&nbsp;&nbsp;";

function createXhr(){
	if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
		xhr=new XMLHttpRequest();
	} else {// code for IE6, IE5
		xhr=new ActiveXObject("Microsoft.XMLHTTP");
	}
}
function go() {
	createXhr();
	checkDiv();
	var url = "ProgressExam?task=create";
	var button = document.getElementById("go");
	button.disabled=true;
	xhr.open("GET", url, true);
	xhr.onreadystatechange = goCallback;
	xhr.send(null);
}
function goCallback(){
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			setTimeout("respServer()", 1500);
		}
	}
}
function respServer(){
	createXhr();
	var url = "ProgressExam?task=ref&key="+key;
	xhr.open("GET", url, true);
	xhr.onreadystatechange = refCallback;
	xhr.send(null);
}
function refCallback(){
	if(xhr.readyState == 4){
		if(xhr.status == 200){
			var percent = xhr.responseXML.getElementsByTagName("percent")[0].firstChild.data;
			var index = processResult(percent);
			for(var i =1;i<=index;i++){
				var elem = document.getElementById("block"+i);
				elem.innerHTML = clear;
				
				elem.style.backgroundColor = bar_color;
				var next_cell = i+1;
				if(next_cell>index&&next_cell<=9){
					document.getElementById("block"+next_cell).innerHTML = percent + "%";
				}
			}
			if(index<9){
				setTimeout("respServer()",1500);
			} else {
				document.getElementById("complete").innerHTML = "complete!";
				document.getElementById("go").disabled = false;
			}
		}
	}
}
function processResult(percent){
	var idx;
	if(percent.length == 1){
		idx = 1;
	} else if(percent.length == 2){
		idx = percent.substring(0,1);
	} else {
		idx = 9;
	}
	return idx;
}
function checkDiv(){
	var progress_bar = document.getElementById("bar");
	if(progress_bar.style.visibility == "visible"){
		clearBar();
		document.getElementById("complete").innerHTML = " ";
	}else{
		progress_bar.style.visibility = "visible";
	}
}
function clearBar(){
	for(var i = 1;i<10;i++){
		var elem = document.getElementById("block"+i);
		elem.innerHTML = clear;
		elem.style.backgroundColor = "white";
	}
}
</script>
</head>
<body>
	<h2>Launch progress bar</h2>
	<input type="button" value="start" id="go" onclick="go();">
	<p>
		<table align="center">
			<tr><td>
				<div id="bar" style="padding:2px;border:solid black 2px;visibility: hidden">
					<span id="block1">&nbsp;&nbsp;&nbsp;</span>
					<span id="block2">&nbsp;&nbsp;&nbsp;</span>
					<span id="block3">&nbsp;&nbsp;&nbsp;</span>
					<span id="block4">&nbsp;&nbsp;&nbsp;</span>
					<span id="block5">&nbsp;&nbsp;&nbsp;</span>
					<span id="block6">&nbsp;&nbsp;&nbsp;</span>
					<span id="block7">&nbsp;&nbsp;&nbsp;</span>
					<span id="block8">&nbsp;&nbsp;&nbsp;</span>
					<span id="block9">&nbsp;&nbsp;&nbsp;</span>
				</div>
			</td></tr>
			<tr><td id="complete" align="center"></td></tr>
		</table>
	</p>
</body>
</html>

      服务端的代码是一个虚拟任务,反应的是任务执行进度,仅仅需要向客户端反馈当前任务执行的进度百分比即可。

package com.any.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ProgressExam
 */
@WebServlet("/ProgressExam")
public class ProgressExam extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private int counter = 1;   
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ProgressExam() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String task = request.getParameter("task");
		String res = "";
		if(task.equals("create")){
			res = "<key>1</key>";
			counter = 1;
		}else{
			String percent = "";
			switch(counter){
			case 1:percent = "10";break;
			case 2:percent = "21";break;
			case 3:percent = "35";break;
			case 4:percent = "52";break;
			case 5:percent = "67";break;
			case 6:percent = "75";break;
			case 7:percent = "88";break;
			case 8:percent = "100";break;
			}
			counter++;
			res = "<percent>"+percent+"</percent>";
		}
		PrintWriter out = response.getWriter();
		response.setContentType("text/xml");
		response.setHeader("Cache-Control", "no-cache");
		out.println("<response>");
		out.println(res);
		out.println("</response>");
		out.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

}

 

分享到:
评论

相关推荐

    asp.net知识库

    如何传值在2个页面之间 :要求不刷新父页面,并且不能用Querystring传值 Asp.net地址转义(分析)加强版 Web的桌面提醒(Popup) Using the Popup Object Click button only once in asp.net 2.0 Coalesys PanelBar ...

    《程序天下:JavaScript实例自学手册》光盘源码

    1.3 页面自动刷新 1.4 页面的后退、刷新、前进 1.5保护网页源代码 1.6 保护自己的网页不被放入框架 1.7 保护自己的网页不被放入框架 1.8 打印页面的出错原因 1.9 当前网页调用其他网页 1.10 倒计时载入页面 1.11 ...

    程序天下:JavaScript实例自学手册

    1.3 页面自动刷新 1.4 页面的后退、刷新、前进 1.5保护网页源代码 1.6 保护自己的网页不被放入框架 1.7 保护自己的网页不被放入框架 1.8 打印页面的出错原因 1.9 当前网页调用其他网页 1.10 倒计时载入页面 1.11 ...

    新坐标企业网站管理系统 v1.0.rar

    8、评论管理、ajax评论系统,无刷新提交数据。 会员管理系统 1、前台快速注册。 2、也可以由管理员在后台添加会员帐号后下发。 3、前台会员管理菜单任意扩展、会员注册资料也可以在模版中扩展。 4、会员组别...

    爱革CMS(门户网站) 3.0.rar

    内容更新了,虽然缓存还没过期,相关的页面同样自动更新。 16.不同栏目可绑定独立域名或二级域名 不需要服务器的支持,只要网站上能够绑定多个域名(几乎所有虚拟主机都支持),就可以在同一个虚拟主机上实现多个...

    爱革CMS(公司网站) 3.0.rar

    内容更新了,虽然缓存还没过期,相关的页面同样自动更新。 16.不同栏目可绑定独立域名或二级域名 不需要服务器的支持,只要网站上能够绑定多个域名(几乎所有虚拟主机都支持),就可以在同一个虚拟主机上实现多个...

    JAVA上百实例源码以及开源项目

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    JAVA上百实例源码以及开源项目源代码

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    新坐标企业网站管理系统 1.0

    8、评论管理、ajax评论系统,无刷新提交数据。 会员管理系统 1、前台快速注册。 2、也可以由管理员在后台添加会员帐号后下发。 3、前台会员管理菜单任意扩展、会员注册资料也可以在模版中扩展。 4、会员组别...

    PHP商城系统 V2.0.5 beta 2.rar

    调整 购物车购买-&gt;支付的流程(修改原增加购买商品-&gt;填写购货人信息-&gt;支付) 到支付页面后若刷新页面将跳转.现调整为只要是用户登录即可看到未支付的订单信息 直接修改即可 调整 原商品阶梯价为商品批发 增加 充值卡...

    网趣网上购物系统HTML静态版v2012版

    一、采用先进的AJAX与XML技术相融合全站静态生成! 网趣网上购物系统HTML静态版 V2012是一套最为先进的网上开店软件!系统采用先进的AJAX技术与XML技术相融生成静态,速度更快!软件代码多重过滤可以第一时间被搜索...

    大名鼎鼎SWFUpload- Flash+JS 上传

     该事件在整个文件的上传过程中定期性的被Flash控件自动触发,用以帮助开发者实时更新页面UI来制作上传进度条。  注意:该事件在Linux版本的Flash Player中存在问题,目前还无法解决。  - 传入参数  file object...

Global site tag (gtag.js) - Google Analytics