AJAX的优点和缺点:
传统的web应用允许用户填写表单(form),当提交表单时就向web服务器发送一个请求。服务器接收并处理传来的表单,然後返回一个新的网页。这个做法浪费了许多带宽,因为在前後两个页面中的大部分HTML代码往往是相同的。由于每次应用的交互都需要向服务器发送请求,应用的响应时间就依赖于服务器的响应时间。这导致了用户界面的响应比本地应用慢得多。
与此不同,AJAX应用可以仅向服务器发送并取回必需的数据,它使用SOAP或其它一些基于 XML的web service接口,并在客户端采 用JavaScript处理来自服务器的响应。因为在服务器和浏览器之间交换的数据大量减少,结果我们就能看到响应更快的应用。同时很多的处理工作可以在发出请求的客户端机器上完成,所以Web服务器的处理时间也减少了。
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息。
Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像 DHTML应用程序那样,Ajax应用程序必须在众多不同的浏览器和平台上经过严格的测试。随着Ajax的成熟,一些简化Ajax使用方法的程序库也相继问世。同样,也出现了另一种辅助程序设计的技术,为那些不支持JavaScript的用户提供替代功能。
对应用Ajax最主要的批评就是,它可能破坏浏览器后退按钮的正常行为[4]。在动态更新页面的情况下,用户无法回到前一个页面状态,这是因为浏览器仅能记下历史记录中的静态页面。一个被完整读入的页面与一个已经被动态修改过的页面之间的差别非常微妙;用户通常都希望单击后退按钮,就能够取消他们的前一次操作,但是在Ajax应用程序中,却无法这样做。不过开发者已想出了种种办法来解决这个问题,当中大多数都是在用户单击后退按钮访问历史记录时,通过建立或使用一个隐藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)
一个相关的观点认为,使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中。该问题的解决方案也已出现,大部分都使用URL片断标识符(通常被称为锚点,即URL中#后面的部分)来保持跟踪,允许用户回到指定的某个应用程序状态。(许多浏览器允许JavaScript动态更新锚点,这使得Ajax应用程序能够在更新显示内容的同时更新锚点。)这些解决方案也同时解决了许多关于不支持后退按钮的争论。
进行Ajax开发时,网络延迟——即用户发出请求到服务器发出响应之间的间隔——需要慎重考虑。不给予用户明确的回应 [5],没有恰当的预读数据 [6],或者对XMLHttpRequest的不恰当处理[7],都会使用户感到延迟,这是用户不欲看到的,也是他们无法理解的[8]。通常的解决方案是,使用一个可视化的组件来告诉用户系统正在进行后台操作并且正在读取数据和内容。
一些手持设备(如手机、PDA等)现在还不能很好的支持Ajax;
用JavaScript作的Ajax引擎,JavaScript的兼容性和DeBug都是让人头痛的事;
Ajax的无刷新重载,由于页面的变化没有刷新重载那么明显,所以容易给用户带来困扰――用户不太清楚现在的数据是新的还是已经更新过的;现有的解决有:在相关位置提示、数据更新的区域设计得比较明显、数据更新后给用户提示等;
对串流媒体的支持没有FLASH、Java Applet好。
说了那么多,还是上真货,分析代码:
客户端代码:
- <?php
- include("../include/dbconn.php");
- //定义分页时每页显示的条数
- $PAGESIZE=15;
- //得到最大页
- $sql="selectcount(*)fromarea";
- $rs=mysql_query($sql);
- //得到查询的结果
- $rowsNum=mysql_result($rs,0);
- //得到总页数
- $maxPage=ceil($rowsNum/$PAGESIZE);
- //判断是否存在当前页值,如果存在,则当前页等于接收到得值,用于显示下面的“滑坨”起始判断
- //if($_GET['nowpage']){
- //$nowpage=$_GET['nowpage'];
- //}else{
- //不存在则设置当前页为1
- //$nowpage=1;
- //}
- ?>
- <!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <htmlxmlns="http://www.w3.org/1999/xhtml">
- <head>
- <style>
- .list{
- width:750px;
- height:460px;
- background-color:#99FF66;
- overflow:auto;
- border:#0000FF1pxdotted;
- margin:0auto;
- }
- .pageNum{
- width:750px;
- height:30px;
- background-color:#999999;
- overflow:auto;
- border:#0000FF1pxdotted;
- margin:0auto;
- text-align:center;
- }
- </style>
- <metahttp-equiv="Content-Type"content="text/html;charset=gb2312"/>
- <title>无标题文档</title>
- <scriptlanguage="javascript"type="text/javascript"src="../include/ajax.js"></script>
- <scriptlanguage="javascript"type="text/javascript">
- varnowpage=1;
- vartotalPage=<?phpecho$maxPage;?>;
- varstartPage=1;
- varendPage=totalPage;
- functioninitPage(){
- varpageStr="";
- //判断总页数是否大于11,如果小于11,不处理起始、最终页码
- if(totalPage>11){
- //判断当前页-10是否存在,如果不存在则不设置起始页码
- if(nowpage-10>0){
- startPage=nowpage-10;
- }
- //判断当前页+9是否超过总页数,如过没有超过,则设置最终页码
- if(nowpage+9<totalPage){
- //设置最终页码
- endPage=nowpage+9;
- }else{
- //解决最后几页不显示的问题
- endPage=totalPage;
- }
- }
- //判断是否显示上一页
- if(nowpage!=1){
- pageStr+="<ahref=javascript:void(0)οnclick=getDataPage("+(nowpage-1)+")>上一页</a>";
- }
- for(vari=startPage;i<=endPage;i++){
- pageStr+="<ahref=javascript:void(0)οnclick=getDataPage("+i+")>";
- //判断是否加粗显示
- if(nowpage==i){
- //设置加粗显示
- pageStr+="<b><fontcolor=yellow>"+i+"</font></b>";
- }else{
- pageStr+=i;
- }
- pageStr+="</a>";
- }
- //判断是否显示下一页
- if(nowpage<totalPage){
- pageStr+="<ahref=javascript:void(0)οnclick=getDataPage("+(nowpage+1)+")>下一页</a>";
- }
- //将当前的字符串显示到div中
- document.getElementById("pageNum").innerHTML=pageStr;
- }
- /*
- 调用ajax引擎,根据页码查询数据库,返回当前的信息
- */
- functiongetDataPage(Page){
- //定义url
- varurl="./getDataPage2.php";
- //定义变量
- varparams="nowPage="+Page+"&pageSize="+<?phpecho$PAGESIZE?>;
- //调用ajax引擎,并制定函数处理服务器返回的结果
- ajaxget(url,params,getDataPageProcess);
- }
- /*
- 处理服务器返回的数据,并显示出来
- */
- functiongetDataPageProcess(xhr){
- //重新初始化开始页
- startPage=1;
- //将json字符串转换为对象
- varresponseObj=eval("("+xhr.responseText+")");
- //接收并设置当前页
- nowpage=parseInt(responseObj.nowPage);
- //重新初始化一下页码显示
- initPage();
- //显示出所有的数据
- varliststr="<table><tr><thwidth='20%'>id</th><thwidth='20%'>名称</th><thwidth='20%'>拼音</th><thwidth='20%'>编码</th><thwidth='20%'>缩写</th></tr>";
- for(vari=0;i<responseObj.areas.length;i++){
- liststr+="<tr><tdalign='center'>"+responseObj.areas[i].id+"</td><tdalign='center'>"+responseObj.areas[i].name+"</td><tdalign='center'>"+responseObj.areas[i].p+"</td><tdalign='center'>"+responseObj.areas[i].code+"</td><tdalign='center'>"+responseObj.areas[i].l+"</td></tr>";
- }
- liststr+="</table>";
- //将拼接完成的table字符串显示在id为list的div中
- document.getElementById("list").innerHTML=liststr;
- }
- </script>
- </head>
- <bodyοnlοad="initPage();getDataPage(1);">
- <divid="list"class="list"></div>
- <divid="pageNum"class="pageNum"></div>
- </body>
- </html>
客户端通过每次传递当前页和每页显示的数据大小到服务器端,服务器端接受参数并按照分页算法,查询对应的数据,并且返回Json格式的字符串,客户端根据服务端返回的Json字符串,通过使用eval方法转换为对象并存放到resopnseObj变量中,则我们可以通过访问responseObj访问查询的数据,最后使用javascript Dom中对象的innerHTML的方法实现数据的显示
服务端代码如下:
- <?php
- //连接数据库
- include("../include/dbconn.php");
- //接收参数,获取当前页
- $nowPage=$_GET['nowPage'];
- $pageSize=$_GET['pageSize'];
- //根据当前页,分页查询
- $sql="selectid,name,p,code,lfromarealimit".($nowPage-1)*$pageSize.",".$pageSize;
- //执行查询操作
- $rs=mysql_query($sql);
- //封装成**数组
- $arr=array();
- while($rows=mysql_fetch_assoc($rs)){
- //每一行数据封装到$arr中,形成的是一个二维数组
- $arr[]=$rows;
- }
- $arr2=array("nowPage"=>$nowPage,"areas"=>$arr);
- //arr2("nowPage"=>$nowPage,"areas"=>arr(row("id"=>,"name"=>,....),array("id"=>,"name"=>,....)))
- //转换成json字符串
- echojson_encode($arr2);
- ?>
以上代码简单清晰,难点在于服务器端如何封装json格式的字符串,但是本文注释比较全了,应该能看明白。
另外,本分页算法只要稍加改动服务器端数据就可以实现,Asp、jsp、.NET的通用