AJAX分頁模板說明和實(shí)例.doc_第1頁
AJAX分頁模板說明和實(shí)例.doc_第2頁
AJAX分頁模板說明和實(shí)例.doc_第3頁
AJAX分頁模板說明和實(shí)例.doc_第4頁
AJAX分頁模板說明和實(shí)例.doc_第5頁
已閱讀5頁,還剩18頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

AJAX表格分頁模板:探討基于Prototype框架的 javascript面向?qū)ο笤O(shè)計(jì) 2008-04-30 作者:笨笨狗 出處: 數(shù)據(jù)分頁顯示,是很普遍的需求,傳統(tǒng)的實(shí)現(xiàn)大多是基于服務(wù)器端導(dǎo)航的,這種設(shè)計(jì)采用同步方式進(jìn)行數(shù)據(jù) 傳輸,用戶體驗(yàn)很差。下面是我在學(xué)習(xí)ajax的過程中,實(shí)現(xiàn)的一個(gè)解決方案,不知道設(shè)計(jì)得怎么樣,所以想發(fā)出來給大家參考下,懇請給予建議和指導(dǎo),狗狗感 激不盡!需求概述:需要將二維數(shù)據(jù)通過表格展現(xiàn)給客戶端,用戶可以事先選擇每頁顯示的條目數(shù),以及數(shù)據(jù)獲取方式(靜態(tài)獲取、異步緩存,以及異步非緩存)。三種方式 簡述如下1、靜態(tài)獲取方式:一次性獲取全部數(shù)據(jù),切換頁面顯示時(shí),不再發(fā)起新的異步查詢,適合少量數(shù)據(jù)的分頁顯示。2、異步緩存方式:分次異步獲取頁面內(nèi)容,并緩存訪問過的頁面內(nèi)容,下一次訪問相同頁面時(shí),直接顯示緩存內(nèi)容,適合量較大且內(nèi)容更新頻率慢的數(shù)據(jù)顯示。3、異步非緩存方式:與第二種方式類似,只是并不緩存頁面內(nèi)容,每次切換新頁面都發(fā)起一次異步請求,適合更新頻率快的數(shù)據(jù)顯示。使用技術(shù):客戶端1、使用table定義二維數(shù)據(jù)結(jié)構(gòu),這是table最合理的使用方式;2、使用css控制頁面展現(xiàn);3、使用javascript發(fā)起異步查詢,以及操作頁面dom元素。為加快開發(fā)速度,采用成熟的Prototype框架簡化復(fù)雜度。服務(wù)器端1、因?yàn)橹皇窃驮O(shè)計(jì),決定采用Groovy腳本生成響應(yīng)數(shù)據(jù)快速展示。只要遵循數(shù)據(jù)傳輸格式,能很快替換為別的實(shí)現(xiàn)。2、采用MySql做數(shù)據(jù)存儲,模仿分頁數(shù)據(jù)。實(shí)現(xiàn)過程:首先,設(shè)計(jì)靜態(tài)效果頁面,注意按照web標(biāo)準(zhǔn)采用合適的xhtml結(jié)構(gòu),并使用css控制其表現(xiàn),頁面代碼如下,為簡單起見,這里把css代碼直接寫到 head頭中:xml 代碼1. 2. 3. 4. 分頁模板 5. 6. * 7. margin:0; 8. padding:0; 9. font:12px宋 體; 10. 11. body 12. text-align:center; 13. 14. #option 15. margin:20pxauto; 16. 17. #items 18. width:4em; 19. 20. #TMPwrap 21. text-align:center; 22. margin-top:10px; 23. 24. #pages 25. margin:10pxauto; 26. border-collapse:collapse; 27. border:1px#666solid; 28. 29. #pagescaption 30. width:100%; 31. 32. #pagesth 33. padding:0.5em; 34. border-right:1px#B9B4A1solid; 35. background:#ECE9D8url(images/theadbg.gif)repeat-xbottom; 36. text-align:center; 37. 38. #pagestd 39. border:1px#B9B4A1solid; 40. border-top:none; 41. padding:0.5em; 42. 43. #navigation 44. margin:10px; 45. text-align:center; 46. 47. #navigationa 48. margin-right:8px; 49. color:black; 50. 51. #navigationa.active 52. text-decoration:none; 53. color:red; 54. cursor:default; 55. 56. .hidden 57. display:none; 58. 59. 60. 61. 62. 63. 每頁顯示條 數(shù): 64. 65. 獲取方式: 66. 67. 靜態(tài) 68. 異 步緩存 69. 異步非緩存 70. 71. 72. 73. 74. 75. 靜態(tài)分頁模板 76. 77. 78. 標(biāo) 題一 79. 標(biāo) 題二 80. 標(biāo) 題三 81. 標(biāo) 題四 82. 標(biāo) 題五 83. 標(biāo) 題六 84. 85. 86. 87. 88. 1 89. 1 90. 1 91. 1 92. 1 93. 1 94. 95. 96. 2 97. 2 98. 2 99. 2 100. 2 101. 2 102. 103. 104. 3 105. 3 106. 3 107. 3 108. 3 109. 3 110. 111. 112. 4 113. 4 114. 4 115. 4 116. 4 117. 4 118. 119. 120. 121. 122. 1 123. 2 124. 3 125. 126. 127. 128. 這樣我們就制作了一個(gè)包含四行數(shù)據(jù)的表格。注意這里html標(biāo)簽的運(yùn)用,使用thead、tbody將表格內(nèi)容分成邏輯 塊,在后面的設(shè)計(jì)中,我們會(huì)把每一頁的內(nèi)容生成一個(gè)tbody。為保證兼容性,對表格的修飾,比如邊框、背景、底色這些,最好在單元格(td或者th)中 設(shè)定,以確保在不同的瀏覽器中具有相似的顯示效果。以上內(nèi)容中,我們用靜態(tài)頁面的方式,設(shè)計(jì)出了分頁模板的表現(xiàn)形式,接下來讓我們利用javascript這個(gè)強(qiáng)大的操盤手 來粘合其余的部分吧。第一步,我們需要設(shè)計(jì)一個(gè)抽象的基類,來實(shí)現(xiàn)代碼復(fù)用(js的OO,不就是為了這個(gè)么,還有就是方便管理代碼而已)。 首先,我們搞個(gè)命名空間來管理基類及其子類: js 代碼1. varTbi=newObject();/全局命名空間 為啥叫“Tbi”?就不要問了,項(xiàng)目組的名稱而已,呵呵:)接下來考慮我們的模板基類,他有什么特征 呢?1、需要持有一個(gè)到頁面容器的引用,以便將自身加入頁面流;2、需要保存用戶設(shè)定的每頁顯示條目數(shù);3、需要保存獲取分頁數(shù)據(jù)的服務(wù)器端地址(URL);這些成員可以通過構(gòu)造器來初始化,除此之外,為了避免數(shù)據(jù)更新發(fā)生混亂(這個(gè)在異步非緩存的時(shí)候需要注意),還要有一個(gè)全局異步對象來獲取數(shù)據(jù),但不需要 通過參數(shù)提供。定義了成員變量,模板對象還需要有可操作的方法:1、構(gòu)造函數(shù):initialize,這個(gè)方法在構(gòu)建Prototype風(fēng)格構(gòu)建類,實(shí)例化對象的時(shí)候會(huì)自動(dòng)調(diào)用。另外有一些技巧下面會(huì)提到;2、在數(shù)據(jù)獲取過程中,顯示等待信息的方法:_showMessage,這里只是簡單顯示一句話,可以按需替換成顯示圖片等;3、顯示模板初始頁面的show方法(其中有兩個(gè)故意設(shè)計(jì)的事件入口,供今后擴(kuò)展使用):A、調(diào)用beforeShow,默認(rèn)為空方法,什么也不做,可按需設(shè)定;B、調(diào)用_display方法,顯示模板初始頁面:a、調(diào)用2中的方法顯示等待信息;b、調(diào)用_catchContent方法異步獲取服務(wù)器數(shù)據(jù)。此方法可由所有模板共享,因此放到基類中達(dá)到代碼重用??梢钥吹剑?我們?yōu)榱思?xì)粒度的控制Prototype的ajax封裝,使用了transport屬性。c、在成功返回服務(wù)器數(shù)據(jù)之后,addContent方法將把分頁內(nèi)容添加到容器中,分兩步來做:(1) addPage方法作為回調(diào)函數(shù)添加模板主體抽象方法,由子類實(shí)現(xiàn)。(2) addNavigation方法根據(jù)實(shí)際情況生成并添加分頁導(dǎo)航抽象方法,我將它在一個(gè)子類中實(shí)現(xiàn)然后演示混入(mixin),其實(shí)完全可以在基類中 提供達(dá)到同樣的代碼復(fù)用效果。js 代碼1. /* 2. *模板基類 3. */ 4. Tbi.Template=Class.create(); 5. Tbi.Ttotype= 6. initialize:function() 7. this._init.apply(this,arguments); 8. , 9. 10. _init:function(wrap,items,catchUrl) 11. this.wrap=$(wrap); 12. this.items=items; 13. this.catchUrl=catchUrl; 14. this.ajax=null;/全局異步對象 15. , 16. 17. /顯 示等待信息 18. _showMessage:function(text) 19. this.wrap.innerHTML=text; 20. , 21. 22. /顯示模板 默認(rèn)頁面 23. show:function() 24. this.beforeShow();/顯示前事件處理入口 25. this._display(); 26. this.afterShow();/顯示后時(shí)間處理入口 27. , 28. 29. /顯 示前事件處理入口 30. beforeShow:function(), 31. 32. _display:function() 33. this._showMessage(正在獲取數(shù)據(jù),請稍等); 34. this._catchContent(); 35. , 36. 37. /取得 默認(rèn)頁面內(nèi)容,由兩個(gè)模板公用 38. _catchContent:function() 39. if(this.ajax) 40. this.ajax.transport.abort(); 41. 42. this.ajax=newAjax.Request( 43. this.catchUrl, 44. 45. method:get, 46. parameters:mode:this.mode,items:this.items, 47. onComplete:this.addContent.bind(this) 48. 49. ); 50. , 51. 52. /添加頁面 內(nèi)容 53. addContent:function(xmlhttp) 54. this.addPage(xmlhttp);/抽象方法,添加頁面內(nèi)容 55. this.addNavigation();/抽象方法,添加分頁導(dǎo)航 56. , 57. 58. /顯示后事 件處理入口 59. afterShow:function() 60. 一些技巧:為了實(shí)現(xiàn)在子類中覆蓋initialize構(gòu)造函數(shù),我們只需要將基類的成員初始化工作委托給_init方法即可,下面會(huì)看到他的作用。模仿事件處理機(jī)制,我們留下了兩個(gè)事件入口beforeShow和afterShow,分別可以設(shè)置顯示前事前和顯示后事件。Prototype為Function對象擴(kuò)展了一個(gè)bind方法和bindAsEventListener方法,可以很方便的將函數(shù)上下文(this) 切換為別的對象,這里,我們切換為模板對象。bind和bindAsEventListener的功用相似,但是有一點(diǎn)區(qū)別,用bind切換的方法,如果 有自動(dòng)傳入的參數(shù),比如事件對象event,那么這個(gè)參數(shù)將被自動(dòng)傳入函數(shù)參數(shù)列表的最后,而后者則是自動(dòng)傳入函數(shù)參數(shù)列表的最前面,這個(gè)技巧很常用。比 如改寫一下上面的代碼,我給onComplete事件傳入一個(gè)自定義參數(shù)tmyArg,使用兩種不同的綁定 方法(xmlhttp是Prototype自動(dòng)傳入回調(diào)函數(shù)的參數(shù)):js 代碼1. /用bind方 法 2. this.addContent.bind(this,myArg) 3. /調(diào)用方式 4. this.addContent(myArg,xmlhttp) 5. 6. 7. /用bindAsEventListener方法 8. this.addContent.bindAsEventListener(this,myArg) 9. /調(diào)用方式 10. this.addContent(xmlhttp,myArg) 第二步,實(shí)現(xiàn)靜態(tài)模板類StaticTemplate。對于靜態(tài)模板,其顯示過程是這樣的:向服務(wù)器發(fā)起一次異步請求,返回所有分頁數(shù)據(jù),服務(wù)器按照客戶 設(shè)定的每頁顯示數(shù)量來生成所有頁,一次新傳回客戶端。每一頁由一對tbody元素定義,然后通過css類名來講所有的頁面隱藏,最后由客戶端js來控制顯 示頁面,初始顯示第一頁。服務(wù)器返回的數(shù)據(jù)格式如下(只要結(jié)構(gòu)一樣就可以了,沒有行、列數(shù)目的限制,這可以參看前一篇文章中的css設(shè)定了解,是可以隨表 格大小伸縮的),總條目數(shù)為6,分了兩頁:xml 代碼1. 2. 靜態(tài)分頁模板 3. 4. 5. 標(biāo)題一 6. 標(biāo)題二 7. 標(biāo)題三 8. 標(biāo)題四 9. 標(biāo)題五 10. 標(biāo)題六 11. 12. 13. 14. 15. 1 16. 1 17. 1 18. 1 19. 1 20. 1 21. 22. 23. 2 24. 2 25. 2 26. 2 27. 2 28. 2 29. 30. 31. 3 32. 3 33. 3 34. 3 35. 3 36. 3 37. 38. 39. 4 40. 4 41. 4 42. 4 43. 4 44. 4 45. 46. 47. 48. 49. 50. 5 51. 5 52. 5 53. 5 54. 5 55. 5 56. 57. 58. 6 59. 6 60. 6 61. 6 62. 6 63. 6 64. 65. 66. StaticTemplate類中,addPage方法統(tǒng)計(jì)table中tbody元素的個(gè)數(shù)來確定總頁數(shù),并附加到對象上。以供 addNavigation方法成分頁導(dǎo)航信息: js 代碼1. this.pageTotal=this.wrap.getElementsByTagName(tbody).length; 在addNavigation方法中,又一次用到了前面提過的bindAsEventListener技巧,并通過切換css類名來達(dá)到突出顯示當(dāng)前頁碼 以及顯示頁面。具體的StaticTemplate代碼實(shí)現(xiàn)如下:js 代碼1. /* 2. *靜態(tài)模板,一次請 求全部數(shù)據(jù) 3. */ 4. Tbi.StaticTemplate=Class.create(); 5. Tbi.StaticTtotype=Object.extend(newTbi.Template(), 6. 7. /* 8. *構(gòu)造函數(shù),實(shí)例化靜態(tài)模板 9. *參數(shù):父容器,每頁顯示條目數(shù),數(shù)據(jù)獲取地址 10. */ 11. initialize:function(wrap,items,catchUrl) 12. this._init(wrap,items,catchUrl); 13. this.mode=static; 14. , 15. 16. /實(shí) 現(xiàn)父類抽象方法,向頁面添加默認(rèn)分頁 17. addPage:function(xmlhttp) 18. this.wrap.innerHTML=xmlhttp.responseText; 19. this.pageTotal=this.wrap.getElementsByTagName(tbody).length; 20. vartable=$(pages); 21. varpages=$A(table.getElementsByTagName(tbody); 22. displayPage=pages0; 23. displayPage.className=; 24. , 25. 26. /實(shí) 現(xiàn)父類抽象方法,向頁面添加分頁導(dǎo)航 27. addNavigation:function() 28. if(this.pageTotal1) 29. varnavigation=document.createElement(div); 30. navigation.id=navigation; 31. varcontext=this; 32. $R(1,this.pageTotal,false).each( 33. function(item) 34. varlink=document.createElement(a); 35. link.href=#; 36. link.onclick=context._changePage.bindAsEventListener(context,link); 37. link.appendChild(document.createTextNode(item); 38. if(item=1) 39. link.className=active; 40. 41. navigation.appendChild(link); 42. 43. ); 44. this.wrap.appendChild(navigation); 45. 46. , 47. 48. /導(dǎo) 航鏈接點(diǎn)擊事件處理函數(shù),切換頁面內(nèi)容,同時(shí)改變導(dǎo)航鏈接樣式(突出顯示當(dāng)前頁) 49. _changePage:function(event,link) 50. varactiveLink=$(#TMPwrapdivaclass=active)0; 51. if(activeLink!=link) 52. varpages=$(#TMPwraptbody); 53. varoldPage=pages.find( 54. function(item) 55. returnitem.className=; 56. 57. ); 58. varnewPage=pageslink.firstChild.nodeValue-1; /inner系列屬性不兼容ff 59. oldPage.className=hidden; 60. newPage.className=; 61. activeLink.className=; 62. link.className=active; 63. 64. Event.stop(event); 65. 66. 67. ); 這樣,我們就完成了靜態(tài)分頁模板的設(shè)計(jì)和實(shí)現(xiàn),下一步是實(shí)現(xiàn)動(dòng)態(tài)異步的兩種獲取方式模板。在前面兩篇文章中,我們實(shí)現(xiàn)了靜態(tài)表格分頁模板,下面讓我們繼續(xù)討論,如何實(shí)現(xiàn)另外兩種數(shù)據(jù)獲取方式的模板。要緩解服務(wù)器的壓力,我們可以這樣做:1、顯示初始頁面也就是第一頁的時(shí)候,我們構(gòu)造好表頭、標(biāo)題和第一頁的數(shù)據(jù),并按照服務(wù)器返回的總頁數(shù)生成導(dǎo)航鏈接,之后將不再更新這部分重復(fù)的內(nèi)容;2、對于每一頁新內(nèi)容,我們在點(diǎn)擊頁碼鏈接的時(shí)候再動(dòng)態(tài)向服務(wù)器獲取數(shù)據(jù),服務(wù)器根據(jù)所請求的頁碼返回特定頁的內(nèi)容,替換掉當(dāng)前顯示的頁面數(shù)據(jù),這樣可以 減少網(wǎng)絡(luò)帶寬的使用,畢竟每次只返回一頁的內(nèi)容;3、對于數(shù)據(jù)更新頻繁的分頁系統(tǒng),就按照上面的辦法每次獲取新數(shù)據(jù);而對于不是很頻繁的數(shù)據(jù),我們提供一種客戶端緩存機(jī)制來加快響應(yīng)速度和減輕服務(wù)器壓 力:通過一個(gè)全局的cache數(shù)組來存放服務(wù)器端之前返回的數(shù)據(jù),在切換頁面的時(shí)候,先查詢緩存,如果沒有命中,再向服務(wù)器發(fā)起異步請求,當(dāng)響應(yīng)到達(dá)的時(shí) 候,也會(huì)將此次數(shù)據(jù)存入緩存以供使用。按照上面的分析,可以發(fā)現(xiàn)這兩種數(shù)據(jù)獲取方式的模板有很多相似的地方,不同的只是緩存與否,我們可以將他們抽象成同一個(gè)類來實(shí)現(xiàn),下面是 javascript代碼,我將在后面就一些需要注意的地方做詳細(xì)講解: js 代碼1. /* 2. *異步模板,每次請求一個(gè)頁面,并緩存瀏覽過的頁面(可選) 3. */ 4. varmixin=newTbi.StaticTemplate();/用于mixin(混入)對象方法addNavigation 5. Tbi.AsyncTemplate=Class.create(); 6. Tbi.AsyncTtotype=Object.extend(newTbi.Template(), 7. 8. initialize:function(wrap,items,catchUrl,option) 9. this._init(wrap,items,catchUrl); 10. this.mode=async; 11. /option為可選參數(shù),設(shè)置初始顯示頁面以及是否緩存頁面 12. this.option=Object.extend(isCache:true,option); 13. if(this.option.isCache) 14. this.cache=newArray();/緩存數(shù)組; 15. 16. , 17. 18. /實(shí) 現(xiàn)父類抽象方法,向頁面添加默認(rèn)分頁 19. addPage:function(xmlhttp) 20. varoriginal=xmlhttp.responseText; 21. varhtml=original.stripScripts(); 22. this.wrap.innerHTML=html; 23. original.evalScripts(); 24. , 25. 26. /mixin(混 入)StaticTemplate類的同名方法,向頁面添加分頁導(dǎo)航 27. addNavigation:mixin.addNavigation,/方法劫 持,重用addNavigation添加分頁導(dǎo)航 28. 29. /導(dǎo) 航鏈接點(diǎn)擊事件處理函數(shù),切換頁面內(nèi)容,同時(shí)改變導(dǎo)航鏈接樣式(突出顯示當(dāng)前頁) 30. _changePage:function(event,link) 31. varactiveLink=$(#TMPwrapdivaclass=active)0; 32. if(activeLink!=link) 33. link.className=active; 34. activeLink.className=; 35. this._displayPage(link); 36. 37. Event.stop(event); 38. , 39. 40. /根 據(jù)緩存標(biāo)志切換頁面內(nèi)容 41. _displayPage:function(link) 42. varpage=link.firstChild.nodeValue; 43. /如果是第一頁,且進(jìn)行緩存的話,直接切換頁面元素的可見性 44. if(page=1&this.cache) 45. $(default).className=; 46. $(swap).className=hidden; 47. 48. /否 則,根據(jù)緩存標(biāo)志,切換顯示其它頁(包括非緩存的默認(rèn)頁) 49. else 50. $(default).className=hidden; 51. varoldPage=$(swap); 52. swapPage=this._prompt(正在獲取數(shù)據(jù)); 53. $(pages).replaceChild(swapPage,oldPage); 54. this._showPage(page); 55. 56. , 57. 58. /顯 示提示信息 59. _prom

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論