- 浏览: 292863 次
- 性别:
- 来自: 昆明
文章分类
最新评论
-
wwangchenyu:
这个工具相当牛逼,太好用了~
Dash:程序员的的好帮手 -
woshi555bin:
...
原创:基于Prototype,利用Canvas绘图实现的web流程图设计器(原型) -
cosmo1987:
赞
Dash:程序员的的好帮手 -
jofy1004:
很强大的工具
Dash:程序员的的好帮手 -
riseliang:
高大上!高大上!高大上!
Dash:程序员的的好帮手
AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(上)
AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(中)
在前面两篇文章中,我们实现了静态表格分页模板,下面让我们继续讨论,如何实现另外两种数据获取方式的模板。要缓解服务器的压力,我们可以这样做:
1、显示初始页面也就是第一页的时候,我们构造好表头、标题和第一页的数据,并按照服务器返回的总页数生成导航链接,之后将不再更新这部分重复的内容;
2、对于每一页新内容,我们在点击页码链接的时候再动态向服务器获取数据,服务器根据所请求的页码返回特定页的内容,替换掉当前显示的页面数据,这样可以减少网络带宽的使用,毕竟每次只返回一页的内容;
3、对于数据更新频繁的分页系统,就按照上面的办法每次获取新数据;而对于不是很频繁的数据,我们提供一种客户端缓存机制来加快响应速度和减轻服务器压 力:通过一个全局的cache数组来存放服务器端之前返回的数据,在切换页面的时候,先查询缓存,如果没有命中,再向服务器发起异步请求,当响应到达的时 候,也会将此次数据存入缓存以供使用。
按照上面的分析,可以发现这两种数据获取方式的模板有很多相似的地方,不同的只是缓存与否,我们可以将他们抽象成同一个类来实现,下面是javascript代码,我将在后面就一些需要注意的地方做详细讲解:
- /*
- * 异步模板,每次请求一个页面,并缓存浏览过的页面(可选)
- */
- var mixin = new Tbi.StaticTemplate(); //用于mixin(混入)对象方法addNavigation
- Tbi.AsyncTemplate = Class.create();
- Tbi.AsyncTemplate.prototype = Object.extend(new Tbi.Template(),
- {
- initialize: function(wrap,items,catchUrl,option){
- this._init(wrap,items,catchUrl);
- this.mode = "async";
- //option为可选参数,设置初始显示页面以及是否缓存页面
- this.option = Object.extend({isCache:true},option);
- if(this.option.isCache){
- this.cache = new Array(); //缓存数组;
- }
- },
- // 实现父类抽象方法,向页面添加默认分页
- addPage: function(xmlhttp){
- var original = xmlhttp.responseText;
- var html = original.stripScripts();
- this.wrap.innerHTML = html;
- original.evalScripts();
- },
- // mixin(混入)StaticTemplate类的同名方法,向页面添加分页导航
- addNavigation: mixin.addNavigation, // 方法劫持,重用addNavigation添加分页导航
- // 导航链接点击事件处理函数,切换页面内容,同时改变导航链接样式(突出显示当前页)
- _changePage: function(event,link){
- var activeLink = $$('#TMPwrap div a[class="active"]')[0];
- if(activeLink != link){
- link.className = "active";
- activeLink.className = "";
- this._displayPage(link);
- }
- Event.stop(event);
- },
- // 根据缓存标志切换页面内容
- _displayPage: function(link){
- var page = link.firstChild.nodeValue;
- // 如果是第一页,且进行缓存的话,直接切换页面元素的可见性
- if(page==1 && this.cache){
- $("default").className = "";
- $("swap").className = "hidden";
- }
- // 否则,根据缓存标志,切换显示其他页(包括非缓存的默认页)
- else{
- $("default").className = "hidden";
- var oldPage = $("swap");
- swapPage = this._prompt("正在获取数据……");
- $("pages").replaceChild(swapPage,oldPage);
- this._showPage(page);
- }
- },
- // 显示提示信息
- _prompt: function(text){
- var swapPage = document.createElement("tbody");
- swapPage.id = "swap";
- var messageTr = document.createElement("tr");
- var messageTd = document.createElement("td");
- messageTd.colSpan = 100;
- messageTd.appendChild(document.createTextNode(text));
- messageTr.appendChild(messageTd);
- swapPage.appendChild(messageTr);
- return swapPage;
- },
- // 根据缓存标志显示页面
- _showPage: function(page){
- if(this.cache&&this.cache["page"+page]){
- this._addPageContent(page); //巧妙重用此方法达到添加页面的效果
- }
- else{
- this._catchPage(page);
- }
- },
- // 异步获取页面内容
- _catchPage: function(page){
- if(this.ajax){
- this.ajax.transport.abort();
- }
- this.ajax = new Ajax.Request(
- this.catchUrl,
- {
- method: "get",
- parameters: {"mode":"page","items":this.items,"page":page},
- onComplete: this._addPageContent.bind(this,page)
- }
- );
- },
- // 添加各分页,并根据缓存标志进行页面缓存
- _addPageContent: function(page,xmlhttp){
- var xml = xmlhttp?xmlhttp.responseXML:this.cache["page"+page];
- if(this.cache&&!this.cache["page"+page]){
- this.cache["page"+page] = xml;
- }
- var oldPage = $("swap");
- var newPage = this._createPage(xml);
- $("pages").replaceChild(newPage,oldPage);
- },
- // 由异步返回的xml,或者缓存数组中的xml信息生成页面内容
- _createPage: function(xml){
- var newPage = document.createElement("tbody");
- newPage.id = "swap";
- var trs = $A(xml.getElementsByTagName("tr"));
- var context = this;
- trs.each(
- function(item,index){
- var tr = document.createElement("tr");
- var tds = $A(item.getElementsByTagName("td"));
- tds.each(
- function(item){
- var value = item.firstChild?item.firstChild.nodeValue:"";
- var td = document.createElement("td");
- td.appendChild(document.createTextNode(value));
- tr.appendChild(td);
- }
- );
- newPage.appendChild(tr);
- }
- );
- return newPage;
- }
- }
- );
一些技巧和说明:
1、AsyncTemplate由前面文章中的Template抽象父类派生而来,因此具有了父类的能力(与静态模板类StaticTemplate共用 _catchContent方法获取初始数据;具有可扩展的显示前、显示后事件入口),达到了代码复用的效果;
2、initialize构造函数中,参数和父类是一样的,只是多了一个可选参数option,用于设置缓存标志(默认为true,即开启缓存),如果开启缓存,则初始化一个缓存数组cache 。这里注意一下默认参数的设置方式,这在Prototype风格的代码中很常见:
- this.option = Object.extend({isCache:true},option);
3、接下来addPage实现父类的抽象方法,作为继承而来的_catchContent方法的回调函数,将处理服务器端返回的数据并显示模板初始页面, 也就是第一页。这里服务器端返回的数据格式如下,注意我们利用了Prototype的扩展evalScripts和stripScripts方法抽取执行 以及删除javascript脚本片段,以达到向客户端返回总页数的效果(后面将利用addNavigation方法和这个总数构建分页导航):
- <table id='pages'>
- <caption>动态分页模板</caption>
- <thead>
- <tr>
- <th>标题一</th>
- <th>标题二</th>
- <th>标题三</th>
- <th>标题四</th>
- <th>标题五</th>
- <th>标题六</th>
- </tr>
- </thead>
- <tbody id='default'>
- <tr>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- <td>1</td>
- </tr>
- <tr>
- <td>2</td>
- <td>2</td>
- <td>2</td>
- <td>2</td>
- <td>2</td>
- <td>2</td>
- </tr>
- <tr>
- <td>3</td>
- <td>3</td>
- <td>3</td>
- <td>3</td>
- <td>3</td>
- <td>3</td>
- </tr>
- <tr>
- <td>4</td>
- <td>4</td>
- <td>4</td>
- <td>4</td>
- <td>4</td>
- <td>4</td>
- </tr>
- </tbody>
- <tbody id="swap" class="hidden">
- <!--新页面交换区-->
- </tbody>
- </table>
- <script type="text/javascript">
- template.pageTotal = 5;
- </script>
这里的tempate是页面上实例化的动态模板对象名称,我们为其添加了一个pageTotal属性,以达到和静态模板类相似的效果,共用
- // mixin(混入)StaticTemplate类的同名方法,向页面添加分页导航
- addNavigation: mixin.addNavigation, // 方法劫持,重用addNavigation添加分页导航
mixin是我们前面实例化的一个addNavigation方法添加导航。(如果觉得耦合太紧,可以修改一下将其赋值给window,两个类都用window对象的同名属性来调用addNavigation生成导航,我觉得没有什么必要)
4、addNavigation方法,我们演示了如何混入(mixin)三方对象的实例方法来达到多继承的目的(这个方法完全可以抽象到父类Template中),其原理就是javascript的函数上下文是动态切换的:
StaticTemplate对象:
- var mixin = new Tbi.StaticTemplate(); //用于mixin(混入)对象方法addNavigation
用这种方式,我们可以给当前类混入任何三方对象的方法,javascript的灵活性在这里展现得淋漓尽致:)
5、其他的代码就不详细介绍了,大家自己看。值得一提的是_catchPage方法中:
- onComplete: this._addPageContent.bind(this,page)
我们又一次用到了bind方法,这里传入的page参数,在函数调用的时候将放到自动传入的xmlhttp参数之前:
- _addPageContent: function(page,xmlhttp){
- var xml = xmlhttp?xmlhttp.responseXML:this.cache["page"+page];
- if(this.cache&&!this.cache["page"+page]){
- this.cache["page"+page] = xml;
- }
- var oldPage = $("swap");
- var newPage = this._createPage(xml);
- $("pages").replaceChild(newPage,oldPage);
- }
另外我们在_showPage中重用_了addPageContent方法,实现了_addPageContent的双重身份:作为回调函数添加新页面内容,或者读取缓存显示页面内容,javascript的代码重用又得以体现:)
6、服务器端返回的新页面数据,由于在IE中不能用inner系列属性直接设定(ie中出了td元素,对于其他的元素,inner系列属性都是只读的,汗一个),因此数据传输不能以内容为中心返回html,而只能返回xml格式:
- <tbody>
- <tr>
- <td>5</td>
- <td>5</td>
- <td>5</td>
- <td>5</td>
- <td>5</td>
- <td>5</td>
- </tr>
- <tr>
- <td>6</td>
- <td>6</td>
- <td>6</td>
- <td>6</td>
- <td>6</td>
- <td>6</td>
- </tr>
- <tr>
- <td>7</td>
- <td>7</td>
- <td>7</td>
- <td>7</td>
- <td>7</td>
- <td>7</td>
- </tr>
- <tr>
- <td>8</td>
- <td>8</td>
- <td>8</td>
- <td>8</td>
- <td>8</td>
- <td>8</td>
- </tr>
- </tbody>
7、接收到服务器传回的上述xml数据后,不能直接用document.getElementsByTagName("tbody")[0]来获得 tbody后直接append到页面,貌似浏览器并不认为这是一个合法的HTML DOM,即使的确是个tbody,汗!只能迭代读取每一行数据来生成,郁闷。这里又遭遇了一个IE的bug:替换页面上的tbody元素,如果先 remove掉已有的,再append新的,如此重复操作,将导致IE发生非法操作,但firefox却一切正常。解决办法是用dom提供的 replaceChild方法来替换,就没有问题了,奇怪。
至此,我们的动态模板也实现了,接下来将讲解服务器端的groovy简单实现,以及示例数据库,请参看:
AJAX表格分页模板(续):服务器端实现
最后我要发一发牢骚:javaeye的代码编辑器真的是bug多多,太郁闷了,我只是想编辑这篇文章,添加下一页的导航,居然搞得数据丢失了。另外,在编 辑已有文章的时候,如果有xml代码,则代码格式必定混乱!每个标签都会缺失关闭符号(左尖括号和斜杠)。而且,不认识Groovy代码,我只能选择 xml来显示,唉,又一个让我失望的blog系统……
评论
早就方出来啦:)看这里
http://scriptfans.iteye.com/blog/82250
这是一个很粗略的原型,可以改进的地方很多,有时间再说了,希望多多指教!
发表评论
-
Javascript数组类型检测:编写更强壮的isArray函数
2009-01-19 13:17 11503在日常开发中,我们经 ... -
我看《Ajax企业级开发》
2008-12-03 15:55 3741Ajax从2005年 ... -
原创:基于Prototype,利用Canvas绘图实现的web流程图设计器(原型)
2008-04-16 10:18 15863刚才在首页看到这么个 ... -
发布一个基于Prototype和Canvas实现的仿Google导航条
2008-04-15 11:42 11191前几天在一个叫做友财 ... -
Prototype1.6以下Element.setStyle()的bug
2007-12-01 11:40 2192问题:如果在frame、iframe页面中使用了setStyl ... -
最值得期待的好书:《Pro CSS and HTML Design Patterns》
2007-05-28 17:24 9477没事上Apress的网站闲逛,偶然发现这本新书 ... -
AJAX表格分页模板(续):服务器端实现
2007-05-23 17:08 8784AJAX表格分页模板:探讨基于Prototype框架的java ... -
为aptana增加firefox预览tab
2007-05-17 14:09 6635一直以来,aptana都是我首选的AJAX前台 ... -
AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(中)
2007-05-16 12:31 13014在上一篇文 ... -
AJAX表格分页模板:探讨基于Prototype框架的javascript面向对象设计(上)
2007-05-14 19:16 12453数据分页显示,是很普遍的需求,传统的实现大多是 ... -
我看《javascript dom编程艺术(dom scripting)》
2007-01-31 02:49 2855这本书在刚出版的时候,编辑就送了一本给我,可惜那段时间出差在外 ... -
腾讯,我无言了
2007-03-14 10:11 2227今天看到一个python群公告上显示有新的文章,好奇点进去想到 ... -
初学者的良师益友——写在《Ajax与Java高级程序设计》出版之际
2007-03-29 02:22 1948最近有朋友向我询问如 ...
相关推荐
火龙果软件工程技术中心 数据分页显示,是很普遍的需求,传统的实现大多是基于服务器端导航的,这种设计采用同步方式进行数据传输,用户体验很差。下面是我在学习ajax的过程中,实现的一个解决方案,不知道设计得...
本示例主要探讨的是一个基于HTML和Ajax实现的简单实用分页模板,它利用Prototype JavaScript框架实现面向对象的设计。 **一、Prototype框架介绍** Prototype是JavaScript的一个开源库,它扩展了JavaScript语言,...
`prototype.js` 文件可能是引入了JavaScript的原型链扩展,这是一种常用的增强JavaScript对象和类的方式,使我们可以像面向对象编程语言一样进行开发。通过扩展JavaScript的原型,我们可以为原生对象添加新的属性和...
AJAX分页是指通过AJAX技术来实现页面数据的动态加载,用户在浏览过程中无需刷新整个页面即可查看不同页的数据。这种方式可以极大地提高网页的响应速度和用户体验。 #### 三、核心代码分析 首先,我们来看一下`...
在本篇"prototype笔记(9)----结合Prototype和JSON开发AJAX"中,我们将深入探讨如何利用Prototype JavaScript库与JSON(JavaScript Object Notation)技术来高效地开发异步JavaScript应用程序,也就是我们常说的AJAX...
本文将深入探讨如何在JavaScript中实现简单易懂的分页功能。 首先,我们需要理解分页的基本概念。分页是将大量数据分成若干个较小的部分,每个部分称为一页,用户可以逐页浏览。在网页中,分页通常包括上一页、...
- **Prototype**:另一个早期的JavaScript框架,提供了`Ajax.Request`和`Ajax.Updater`等方法。 - **AngularJS**:Google开发的MVC(Model-View-Controller)框架,内置了强大的Ajax功能,如`$http`服务。 - **Vue....
AJAX(Asynchronous JavaScript and XML)是一种在无需刷新整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新。AJAX的核心是JavaScript对象XMLHttpRequest,它...
7. **Ajax实战**:深入探讨Ajax在实际项目中的应用,如表单验证、实时数据刷新、无刷新分页等常见场景。 8. **Ajax与AJAX库**:介绍jQuery、Prototype等流行的Ajax库,简化Ajax开发过程。 9. **Ajax性能优化**:...
本文将结合标题“jquery prototype dojo 之 Ajax example 和学习总结”以及描述,深入探讨jQuery、Prototype和Dojo这三种JavaScript库中的Ajax应用,以及相关的学习要点。 首先,jQuery是目前最流行的JavaScript库...
- **Dojo, Prototype, YUI**:其他一些JavaScript框架也提供了强大的Ajax支持,各有特色,可根据项目需求选择。 4. **异步数据处理** - **动态加载内容**:通过Ajax实现页面部分内容的动态加载,如分页、无限滚动...
**Ajax(Asynchronous JavaScript and XML)技术是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。在JavaScript库Prototype中,Ajax的使用大大简化了与服务器的异步交互过程。本篇文章将深入探讨如何...
AJAX分页技术是基于异步请求的一种分页方式,它可以在不刷新整个页面的情况下动态加载和显示新内容。这种方式可以显著提高用户的浏览体验,特别是在大数据量的情况下,传统的全页刷新会带来较大的延迟,而使用AJAX...
**基于Java的国产Ajax框架 Buffalo** Ajax(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,提升...
Ajax技术允许前端页面无刷新地与服务器进行交互,提升用户体验,而Struts框架则是一个基于MVC(Model-View-Controller)设计模式的Java Web应用框架,它简化了后台逻辑处理。将两者结合起来可以实现高效、流畅的用户...
**AJAX(Asynchronous JavaScript and XML)是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它通过在后台与服务器进行少量数据交换,使网页实现异步更新,提升了用户体验。在本压缩包"AJAX高级程序...
Ajax,全称为"Asynchronous JavaScript and XML",是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。它的核心是JavaScript异步通信,通过XMLHttpRequest对象与服务器进行数据交互,使得用户界面更加...
Ajax,全称Asynchronous JavaScript and XML(异步JavaScript与XML),是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。这种技术的核心在于利用JavaScript进行客户端脚本编程,结合XML或者JSON等...