首页 | 新闻 | 生活 | 奥运 | 镇区 | 健康 | 新经济 | 教育 人才 | 企业 | 房交会 | 汽车 | 旅游  | 文明城市 | 家电 网络 | 财经金融
logo jiao
专题 | 商机 | 娱乐 | 小说                                  设为首页 | 收藏此文
财 经 | 汽 车 | 国 内 | 国 际 | 八 卦 | 服 饰 | 购 物 | 美 食 | 科 技 | 人 才 | 体 育 | 健 康 | 品 牌 | 教 育 | 数 码 | 娱 乐 | 军 事
banner1 banner2
当前的位置 wangzhi 首页 >> IT家电 >> 互联网技术 >> 编程艺术 >> 正文
  fangdajing 请输入字
 
图1.后退、前进和刷新的历史记录按钮显示在左侧,不可用状态显示在右侧

编写类

我们来看看历史堆栈中需要存储的数据或属性。前面已经讨论了堆栈(数组)和指针。stack_limit属性可以防止因为数据过多而造成的cookie溢出(参见清单1)。在实践中,我们希望在删除最老的记录之前能够存储40-50个事件。出于测试的目的,我们将该值设置为15。

清单1.历史堆栈的构造,包括类的属性

  functionHistoryStack()
{
 this.stack=newArray();
 this.current=-1;
 this.stack_limit=15;
}
除了这三个属性外,该类还需要一些方法来添加元素、检索堆栈数据以及将堆栈数据保存到浏览器cookie中。首先看一看addResource()方法,它用于将记录压入历史堆栈的堆栈顶部(参见清单2)。注意,如果堆栈的长度超过了stack_limit,那么最老的记录将从堆栈中移走。

清单2.addResource()方法,向历史堆栈的堆栈顶部添加记录

  HistoryStack.prototype.addResource=function(resource)
{
 if(this.stack.length>0){
this.stack=this.stack.slice(0,this.current+1);
 }
 this.stack.push(resource);
 while(this.stack.length>this.stack_limit){
this.stack.shift();
 }
 this.current=this.stack.length-1;
 this.save();
};
给历史堆栈添加的以下三个方法用于从该类中获取信息(参见清单3)。getCurrent()返回堆栈指针指向的当前记录,这在堆栈中导航的时候非常有用。hasPrev()和hasNext()方法返回Boolean值,告诉我们当前记录之前或之后是否还有记录,或者指示我们到达了堆栈顶部或堆栈尾部。这些方法很简单,但是确定后退和前进按钮的状态时很有用。

清单3.历史堆栈定义的方法

  HistoryStack.prototype.addResource=function(resource)
HistoryStack.prototype.getCurrent=function()
{
 returnthis.stack[this.current];
};

HistoryStack.prototype.hasPrev=function()
{
 return(this.current>0);
};

HistoryStack.prototype.hasNext=function()
{
 return(this.current<this.stack.length-1&&this.current>-1);
};
现在就可以向历史堆栈中添加记录并确定所在的位置了。但还是无法在堆栈中导航。清单4中定义的go()方法允许我们在堆栈中来回移动。通过传递正或负的增量就可以在堆栈中向前或向后移动。这与JavaScript内置的location.go()方法类似。既然模仿内置功能,为何不根据这些已有的方法建立模型呢?

此外,我们还可用该方法实现刷新功能。可以通过传递正或负的参数在堆栈中导航。传递零时则会刷新当前页面。

清单4.历史堆栈的go()方法

  HistoryStack.prototype.go=function(increment)
{
 //Goback...
 if(increment<0){
this.current=Math.max(0,this.current+increment);

//Goforward...
 }elseif(increment>0){
this.current=Math.min(this.stack.length-1,this.current+increment);
//Reload...
 }else{
location.reload();
 }
 this.save();
};
到目前为止,只要HistoryStack对象存在于当前文档中,这个新建的类就能正常工作。我们已经讨论了刷新页面会造成数据丢失的问题,现在来解决它。清单5中添加了在浏览器cookie中设置和访问数据的方法。所要做的只是设置每个cookie的名称值对。因为只需要在浏览器会话中保存cookie,而不需要设置有效期。为了简化示例,我们不考虑其他参数,如secure、domain和path。

注意:如果该类需要对cookie做复杂处理,更明智的办法是使用完全独立的cookie管理类。建立和读取cookie有点偏离历史堆栈的正题。如果JavaScript允许指定方法和属性访问的作用域,也可以将这些方法设成私有的。

清单5.建立和访问浏览器cookie的方法

  HistoryStack.prototype.setCookie=function(name,value)
{
 varcookie_str=name+"="+escape(value);
 document.cookie=cookie_str;
};

HistoryStack.prototype.getCookie=function(name)
{
 if(!name)return'';
 varraw_cookies,tmp,i;
 varcookies=newArray();
 raw_cookies=document.cookie.split(';');
 for(i=0;i<raw_cookies.length;i++){
tmp=raw_cookies[i].split('=');
cookies[tmp[0]]=unescape(tmp[1]);
 }
 if(cookies[name]!=null){
returncookies[name];
 }else{
return'';
 }
};
定义了管理任何cookie的方法之后,可以编写另外两个类专门处理历史堆栈的类。save()方法将堆栈转化成字符串并保存到cookie中,load()重新将字符串解析成用于管理历史堆栈的数组(参见清单6)。

清单6.save()和load()方法

  HistoryStack.prototype.save=function()
{
 this.setCookie('CHStack',this.stack.toString());
 this.setCookie('CHCurrent',this.current);
};

HistoryStack.prototype.load=function()
{
 vartmp_stack=this.getCookie('CHStack');
 if(tmp_stack!=''){
this.stack=tmp_stack.split(',');
 }

 vartmp_current=parseInt(this.getCookie('CHCurrent'));
 if(tmp_current>=-1){
this.current=tmp_current;
 }
};

 

 

测试类

可以用简单的HTML页面和一些JavaScript来测试完成的类。测试页面将在上方显示历史记录按钮,只有活动的按钮是突出显示并且可以单击的。我们没有建立复杂的测试应用程序,该页面在每次单击链接时仅仅生成随机数。这些数字就是记录到历史堆栈中的事件。堆栈也在页面上显示,指针标记的当前记录用粗体显示。

清单7.测试历史堆栈的简单HTML页面

  <html>
<head>
<title></title>
</head>

<body>

<divid="historybuttons"></div>
<div>
<ahref="#">AddRandom
Resource</a>
</div>
<divid="output"style="margin-top:40px;"></div>

</body>
</html>
在该HTML页面的头部需要添加清单8所示的JavaScript代码。这段代码首先实例化一个新的历史堆栈对象,并载入可能已经保存到浏览器cookie中的所有数据。

我们定义了四个do_*()函数,这些事件处理程序将添加到后退、前进和刷新按钮的链接中,此外还有AddRandomResource链接,如清单7所示。

display()函数检查历史记录对象的当前状态,并为历史记录按钮生成HTML。它还生成历史记录中存储的项目列表。

清单8.集成历史记录类和测试页面的JavaScript

  <scripttype="text/javascript"src="history.js"></script>
<scripttype="text/javascript">

varmyHistory=newHistoryStack();
myHistory.load();

functiondo_add()
{
 varnum=Math.round(Math.random()*1000);
 myHistory.addResource(num);
 display();
 returnfalse;
}

functiondo_back()
{
 myHistory.go(-1);
 display();
}

functiondo_forward()
{
 myHistory.go(1);
 display();
}

functiondo_reload()
{
 myHistory.go(0);
}

functiondisplay()
{
 //Displayhistorybuttons
 varstr='';
 if(myHistory.hasPrev()){
str+='<ahref="#">'
+'<imgsrc="icons/back_on.gif"alt="Back"
/></a>';
 }else{
str+='<imgsrc="icons/back_off.gif"alt=""/>';
 }
 if(myHistory.hasNext()){
str+='<ahref="#">'
+'<imgsrc="icons/forward_on.gif"alt="Forward"/>'
+'</a>';
 }else{
str+='<imgsrc="icons/forward_off.gif"alt=""/>';
 }
 str+='<ahref="#">'
+'<imgsrc="icons/reload.gif"alt="Reload"
/></a>';
 document.getElementById("historybuttons").innerHTML=str;

 //Displaythecurrenthistorystack,highlightingthecurrent
 //position.
 varstr='<div>History:</div>';
 for(i=0;i<myHistory.stack.length;i++){
if(i==myHistory.current){
 str+='<div><b>'+myHistory.stack[i]+
'</b></div>';
}else{
 str+='<div>'+myHistory.stack[i]+'</div>';
}
 }
 document.getElementById("output").innerHTML=str;
}

window.onload=function(){
 display();
};
</script>
运行该测试页面,可以看到历史记录按钮反映了历史堆栈的状态(见图2)。比如,第一次加载页面时,按钮都是灰色的。向堆栈中添加一些记录后,后退按钮就变成活动的了。如果在堆栈中回退,前进按钮就变亮了。还要注意的是,如果单击几次后退然后再单击Add,那么堆栈会被截掉一部分,新的事件被压入缩短的堆栈顶部。

 
图2.历史堆栈的测试页面

 

在第1部分中,相册中的每个链接都是由get_table_link()和get_image_link()两个函数生成的。通过编辑这些函数,可以在调用Sajax函数之前让该函数先调用历史堆栈。清单9以粗体显示了这些变化。

清单9.get_table_link()和get_image_link()函数的更新版本

  functionget_table_link($title,$start,$step){
 $link="myHistory.addResource('table-$start-$step');"
 ."x_get_table($start,$step,to_window);"
 ."returnfalse;";
 return'<ahref="#">'.$title.'</a>';
}

functionget_image_link($title,$index){
 $link="myHistory.addResource('image-$index');"
 ."x_get_image($index,to_window);"
 ."returnfalse;";
 return'<ahref="#">'.$title.'</a>';
}
当应用程序进行Sajax调用时,to_window()作为回调函数在页面上重新生成HTML。在测试应用程序中,我们用函数display()(清单8)完成了两项任务:更新页面输出和更新历史记录按钮的状态。现在将在已有的to_window()函数体中添加下列函数调用:

  display_history_buttons();
该函数的定义如清单10所示。

清单10.display_history_buttons()函数

  functiondisplay_history_buttons()
{
 varstr='';
 if(myHistory.hasPrev()){
str+='<ahref="#">
<imgsrc="icons/back_on.gif"alt="Back"/></a>';
 }else{
str+='<imgsrc="icons/back_off.gif"alt=""/>';
 }
 if(myHistory.hasNext()){
str+='<ahref="#">
<imgsrc="icons/forward_on.gif"alt="Forward"/></a>';
 }else{
str+='<imgsrc="icons/forward_off.gif"alt=""/>';
 }
 str+='<ahref="#">
<imgsrc="icons/reload.gif"alt="Reload"/></a>';
 document.getElementById("historybuttons").innerHTML=str;
}
在开始跟踪相册应用程序的历史记录之前,只需要在页面加载过程中调用x_get_table()函数即可。这样就可以调用通过Sajax显示的初始表。

现在已经有了历史堆栈,但是我们不希望每次打开该应用程序时都要从头开始。相反,我们希望从离开的地方开始。因此需要添加load_current()函数以扩展应用程序,加载页面时会调用该函数。添加后退和前进按钮处理程序时,还将调用该函数,根据保存到历史堆栈中的事件ID来更新页面。

清单11.load_current()函数

  functionload_current()
{
 //Noexistinghistory.
 if(myHistory.stack.length==0){
x_get_table(to_window);
myHistory.addResource('table-0-5');
 
//Loadfromhistory.
 }else{
varcurrent=myHistory.getCurrent();
varparams=current.split('-');
if(params[0]=='table'){
 x_get_table(params[1],params[2],to_window);
}elseif(params[0]=='image'){
 x_get_image(params[1],to_window);
}
 }
}
onload处理程序需要进行相应的修改:

  window.onload=function(){
 load_current();
};
最后,添加清单12中的历史记录按钮处理例程。注意处理程序和测试应用程序的相似性。

清单12.历史记录按钮事件处理程序

  functiondo_back()
{
 myHistory.go(-1);
 load_current();
}

functiondo_forward()
{
 myHistory.go(1);
 load_current();
}

functiondo_reload()
{
 myHistory.go(0);
}
至此就完成了历史堆栈到相册应用程序的集成。完成后的产品如图3所示。

 
图3.与相册应用程序结合的历史记录按钮>
新闻评论
正在加载评论列表...
评论表单加载中...
 

结合AJAX的PHP开发之后退、前进和刷新

来源:互联网 时间:2008-10-15 9:09:55 点击: 今日评论:
=

简介

第1部分介绍了如何用Sajax、PHP和JavaScript开发基本的相册。在为应用程序建立历史堆栈的过程中,我们将依靠客户端技术,并将其直接与第1部分的代码结合在一起。本文假设读者了解JavaScript和浏览器cookie。

在浏览器中保存状态

在网上冲浪的时候,总是从一个页面到另一个页面,从一个站点到另一个站点。在这个过程中,Web浏览器忠实地记录了您曾经到过何处的历史记录,创建了一条面包屑型(breadcrumbs)数字轨迹,沿着这条轨迹能够一步一步地回到出发点。后退按钮允许您回到上一个动作之前所在的位置,从这个意义上说它就是Web上的撤销按钮。

Web是一种按页划分的的媒体。浏览器工具栏中的后退和前进按钮指引着浏览器从一个页面移动到另一个页面。当Macromedia的Flash风行一时的时候,开发人员和用户发现富互联网应用程序(RichInternetApplication,RIA)打破了这种模式。用户可以在几个站点上浏览,然后登录一个基于Flash的网站,在这个网站上消磨几分钟。当用户单击后退按钮时,游戏结束了。用户没有回到先前的那个Flash站点,完全不知道到了什么地方。

对于完全基于Ajax的网站——RIA的另一种形式,情况也是如此。允许用户与一个页面进行多次交互的网站很容易受到后退按钮的困扰,或者受到任何历史记录按钮的困扰(就此而言)。前进和重载按钮的问题与后退按钮的问题一样。Web浏览器内置的内部历史记录机制是一个不可逃避的问题。出于安全的原因,开发人员不能篡改浏览器历史记录或者任何相关按钮。还有可用性的问题。设想一下,如果后退按钮突然弹出一个神秘的警告提示或者用户被打发到一个新的网站上去,用户该是多么困惑。

构建历史堆栈

虽然不能改变浏览器历史记录,但是可以自己构建一个在RIA中使用的历史记录。显然,它在某种程度上应该与浏览器的标准导航工具分开,但正如前面所说的,富应用程序在一定程度上背离了Web的页面到页面的标准模式。

我们将建立一个堆栈来管理应用程序的历史事件记录,也就是说存储一个列表,在表的最后添加元素。堆栈用于按照后进先出(LIFO)的顺序存储数据。虽然回退的时候并没有删除堆栈顶部的数据,但这个模型跟我们的需要非常接近。在JavaScript中,堆栈可以用数组来管理。

与堆栈在一起的还有一个指针,指示我们在堆栈中的当前位置。当我们在应用程序中单击的时候,新的事件将被压入堆栈顶部,指针指向最后添加的元素。单击应用程序的后退和前进按钮时,不会在堆栈中添加新的事件,而是移动堆栈的指针。想一想使用后退按钮时历史堆栈中会发生什么:浏览器返回上一次查看的页面,原来不能用的前进按钮突然之间变得可用了。浏览新的页面时,前进按钮再次变成灰色。浏览器历史记录中较晚保存的元素将被弹出堆栈,新的事件被压入堆栈顶部。我们将在自己创建的历史堆栈中再现这种行为。

我们的目标是创建一组可用的历史记录按钮:后退、前进和刷新,如图1所示。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


che
  分类信息 更多>>
 

  • 高剑:适度竞争的关键在于开放
  • 李坚:市场化是慈善超市可行之道
  • 唐彬:以行业协会发育应对市场风险无
  • 高剑:防治“走佬” 需撒两张网
  • 吕志英:假如墙上的洞也堵了
  • 程绍德:治“牛皮癣”岂能“以毒攻毒
  • 南海渔民:楼市新政,请莫过度解读
  • 唐彬:服务型政府是民营经济的推力
  • 李坚:科学素质调查的提醒
  • 谢锐勤:行政权不应“侵略”立法权领
  • 余以为:区域一体化重在产权明晰
  • 吕志英:物管破案让警察干什么
  • 肖功俊:“权力变通”可抵立法权之缺
  • 李坚:管理摊贩见证城市管理智慧
  • 守浊:小出租屋的大乾坤
  •   频道精选 更多>>
      TU1   TU2
     
  • 东莞东火车站指定春运电话订票取票点<
  • 东莞交通违章查询
  • 徐锦祉:金融危机下的中国酒店业
  • 东莞阳光网--魅力东莞
  • 成人脱产本科能考公务员吗?
  • 二手房买卖合同样本
  • 二手车市_阳光汽车
  • 二手汽车买卖合同
  • 东莞汽车违章罚款滞纳金解释
  • 娱乐圈先签协议后结婚 章子怡若离婚无
  • 拿万名富豪当摇钱树的女人(图)
  • 东莞交通违章处理程序规定细则
  • 厚街警方摧毁一恶势力团伙
  • 东莞电信189昨放号 可选70多款定制手
  • 周慧敏再度穿上古典宫廷装,性感迷人

  •   热点新闻 更多>>
     
    TU1   [省内休闲]梅州雁鸣湖、... 著名摄影家是如何工作的 超低价享受慵懒冬季热门 12月份 十个最美的地方(
  • 中国教育培训行业进入新一轮大并购时
  • 英语美文:Christmas morning 圣诞的
  • 面对大学自主招生 学生该如何保持良好
  • 广东保送生录取26日进行 8类考生具保
  • 冬季出游不可错过的五大圣地(组图)
  • 当心!中国最黑的十三个旅游景点(组图
  • 秋高气爽 让我们自己动手自助烧烤(图)



  •  
    全球纺织网美食导报·东莞饮食东莞汽车网搜房网富民服装网东莞台商网东莞经贸局东莞市消防网世惠生活网东莞市民政局
    东莞卫生局东莞图书馆E屋不动产阳光物流网东莞时尚东莞搜狐分类东莞租房-搜房网东莞之窗东莞二手房东莞分类信息网
    东莞招聘网东莞团购广东山东商会雷州壹网东莞网站优化卓博人才网东莞市人民政府搜优人才网
    lianjie
    关于我们 | 版权声明 | 网站地图 | 招聘信息 | 广告服务 | 联系我们 | 友情链接
    版权所有 copyright: http://www.dgce.org 粤ICP备09013760号
    地址:东莞市东城中路辉煌大厦4A16 邮编:523000
    电话:0769-22024906 22024908 传真:0769-22024907 投稿信箱:info@dgce.org
    如您有任何意见或建议,请与我们联系:webmaster@dgce.org
    ih
    CHI flat ironjimmy chooGHD straightenerHerve legerManolo blahnikJimmy chooChristian louboutinChristian louboutin saleChristian louboutin shoesChristian louboutinJordan shoesAir jordan shoesRosetta StoneRosetta Stone SpanishVibram five fingersVibram five fingers saleSennheiser microphonesShure microphonesNike shoxCoach handbagsTiffany JewelryMoncler jackets