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

下載本文檔

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

文檔簡介

AJAX表格分頁模板:探討基于Prototype框架的 javascript面向?qū)ο笤O計 2008-04-30 作者:笨笨狗 出處: 數(shù)據(jù)分頁顯示,是很普遍的需求,傳統(tǒng)的實現(xiàn)大多是基于服務器端導航的,這種設計采用同步方式進行數(shù)據(jù) 傳輸,用戶體驗很差。下面是我在學習ajax的過程中,實現(xiàn)的一個解決方案,不知道設計得怎么樣,所以想發(fā)出來給大家參考下,懇請給予建議和指導,狗狗感 激不盡!需求概述:需要將二維數(shù)據(jù)通過表格展現(xiàn)給客戶端,用戶可以事先選擇每頁顯示的條目數(shù),以及數(shù)據(jù)獲取方式(靜態(tài)獲取、異步緩存,以及異步非緩存)。三種方式 簡述如下1、靜態(tài)獲取方式:一次性獲取全部數(shù)據(jù),切換頁面顯示時,不再發(fā)起新的異步查詢,適合少量數(shù)據(jù)的分頁顯示。2、異步緩存方式:分次異步獲取頁面內(nèi)容,并緩存訪問過的頁面內(nèi)容,下一次訪問相同頁面時,直接顯示緩存內(nèi)容,適合量較大且內(nèi)容更新頻率慢的數(shù)據(jù)顯示。3、異步非緩存方式:與第二種方式類似,只是并不緩存頁面內(nèi)容,每次切換新頁面都發(fā)起一次異步請求,適合更新頻率快的數(shù)據(jù)顯示。使用技術:客戶端1、使用table定義二維數(shù)據(jù)結(jié)構(gòu),這是table最合理的使用方式;2、使用css控制頁面展現(xiàn);3、使用javascript發(fā)起異步查詢,以及操作頁面dom元素。為加快開發(fā)速度,采用成熟的Prototype框架簡化復雜度。服務器端1、因為只是原型設計,決定采用Groovy腳本生成響應數(shù)據(jù)快速展示。只要遵循數(shù)據(jù)傳輸格式,能很快替換為別的實現(xiàn)。2、采用MySql做數(shù)據(jù)存儲,模仿分頁數(shù)據(jù)。實現(xiàn)過程:首先,設計靜態(tài)效果頁面,注意按照web標準采用合適的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. 標 題一 79. 標 題二 80. 標 題三 81. 標 題四 82. 標 題五 83. 標 題六 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. 這樣我們就制作了一個包含四行數(shù)據(jù)的表格。注意這里html標簽的運用,使用thead、tbody將表格內(nèi)容分成邏輯 塊,在后面的設計中,我們會把每一頁的內(nèi)容生成一個tbody。為保證兼容性,對表格的修飾,比如邊框、背景、底色這些,最好在單元格(td或者th)中 設定,以確保在不同的瀏覽器中具有相似的顯示效果。以上內(nèi)容中,我們用靜態(tài)頁面的方式,設計出了分頁模板的表現(xiàn)形式,接下來讓我們利用javascript這個強大的操盤手 來粘合其余的部分吧。第一步,我們需要設計一個抽象的基類,來實現(xiàn)代碼復用(js的OO,不就是為了這個么,還有就是方便管理代碼而已)。 首先,我們搞個命名空間來管理基類及其子類: js 代碼1. varTbi=newObject();/全局命名空間 為啥叫“Tbi”?就不要問了,項目組的名稱而已,呵呵:)接下來考慮我們的模板基類,他有什么特征 呢?1、需要持有一個到頁面容器的引用,以便將自身加入頁面流;2、需要保存用戶設定的每頁顯示條目數(shù);3、需要保存獲取分頁數(shù)據(jù)的服務器端地址(URL);這些成員可以通過構(gòu)造器來初始化,除此之外,為了避免數(shù)據(jù)更新發(fā)生混亂(這個在異步非緩存的時候需要注意),還要有一個全局異步對象來獲取數(shù)據(jù),但不需要 通過參數(shù)提供。定義了成員變量,模板對象還需要有可操作的方法:1、構(gòu)造函數(shù):initialize,這個方法在構(gòu)建Prototype風格構(gòu)建類,實例化對象的時候會自動調(diào)用。另外有一些技巧下面會提到;2、在數(shù)據(jù)獲取過程中,顯示等待信息的方法:_showMessage,這里只是簡單顯示一句話,可以按需替換成顯示圖片等;3、顯示模板初始頁面的show方法(其中有兩個故意設計的事件入口,供今后擴展使用):A、調(diào)用beforeShow,默認為空方法,什么也不做,可按需設定;B、調(diào)用_display方法,顯示模板初始頁面:a、調(diào)用2中的方法顯示等待信息;b、調(diào)用_catchContent方法異步獲取服務器數(shù)據(jù)。此方法可由所有模板共享,因此放到基類中達到代碼重用??梢钥吹?, 我們?yōu)榱思毩6鹊目刂芇rototype的ajax封裝,使用了transport屬性。c、在成功返回服務器數(shù)據(jù)之后,addContent方法將把分頁內(nèi)容添加到容器中,分兩步來做:(1) addPage方法作為回調(diào)函數(shù)添加模板主體抽象方法,由子類實現(xiàn)。(2) addNavigation方法根據(jù)實際情況生成并添加分頁導航抽象方法,我將它在一個子類中實現(xiàn)然后演示混入(mixin),其實完全可以在基類中 提供達到同樣的代碼復用效果。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. /顯示模板 默認頁面 23. show:function() 24. this.beforeShow();/顯示前事件處理入口 25. this._display(); 26. this.afterShow();/顯示后時間處理入口 27. , 28. 29. /顯 示前事件處理入口 30. beforeShow:function(), 31. 32. _display:function() 33. this._showMessage(正在獲取數(shù)據(jù),請稍等); 34. this._catchContent(); 35. , 36. 37. /取得 默認頁面內(nèi)容,由兩個模板公用 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();/抽象方法,添加分頁導航 56. , 57. 58. /顯示后事 件處理入口 59. afterShow:function() 60. 一些技巧:為了實現(xiàn)在子類中覆蓋initialize構(gòu)造函數(shù),我們只需要將基類的成員初始化工作委托給_init方法即可,下面會看到他的作用。模仿事件處理機制,我們留下了兩個事件入口beforeShow和afterShow,分別可以設置顯示前事前和顯示后事件。Prototype為Function對象擴展了一個bind方法和bindAsEventListener方法,可以很方便的將函數(shù)上下文(this) 切換為別的對象,這里,我們切換為模板對象。bind和bindAsEventListener的功用相似,但是有一點區(qū)別,用bind切換的方法,如果 有自動傳入的參數(shù),比如事件對象event,那么這個參數(shù)將被自動傳入函數(shù)參數(shù)列表的最后,而后者則是自動傳入函數(shù)參數(shù)列表的最前面,這個技巧很常用。比 如改寫一下上面的代碼,我給onComplete事件傳入一個自定義參數(shù)tmyArg,使用兩種不同的綁定 方法(xmlhttp是Prototype自動傳入回調(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) 第二步,實現(xiàn)靜態(tài)模板類StaticTemplate。對于靜態(tài)模板,其顯示過程是這樣的:向服務器發(fā)起一次異步請求,返回所有分頁數(shù)據(jù),服務器按照客戶 設定的每頁顯示數(shù)量來生成所有頁,一次新傳回客戶端。每一頁由一對tbody元素定義,然后通過css類名來講所有的頁面隱藏,最后由客戶端js來控制顯 示頁面,初始顯示第一頁。服務器返回的數(shù)據(jù)格式如下(只要結(jié)構(gòu)一樣就可以了,沒有行、列數(shù)目的限制,這可以參看前一篇文章中的css設定了解,是可以隨表 格大小伸縮的),總條目數(shù)為6,分了兩頁:xml 代碼1. 2. 靜態(tài)分頁模板 3. 4. 5. 標題一 6. 標題二 7. 標題三 8. 標題四 9. 標題五 10. 標題六 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)計table中tbody元素的個數(shù)來確定總頁數(shù),并附加到對象上。以供 addNavigation方法成分頁導航信息: js 代碼1. this.pageTotal=this.wrap.getElementsByTagName(tbody).length; 在addNavigation方法中,又一次用到了前面提過的bindAsEventListener技巧,并通過切換css類名來達到突出顯示當前頁碼 以及顯示頁面。具體的StaticTemplate代碼實現(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ù),實例化靜態(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. /實 現(xià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. /實 現(xiàn)父類抽象方法,向頁面添加分頁導航 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. /導 航鏈接點擊事件處理函數(shù),切換頁面內(nèi)容,同時改變導航鏈接樣式(突出顯示當前頁) 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)分頁模板的設計和實現(xiàn),下一步是實現(xiàn)動態(tài)異步的兩種獲取方式模板。在前面兩篇文章中,我們實現(xiàn)了靜態(tài)表格分頁模板,下面讓我們繼續(xù)討論,如何實現(xiàn)另外兩種數(shù)據(jù)獲取方式的模板。要緩解服務器的壓力,我們可以這樣做:1、顯示初始頁面也就是第一頁的時候,我們構(gòu)造好表頭、標題和第一頁的數(shù)據(jù),并按照服務器返回的總頁數(shù)生成導航鏈接,之后將不再更新這部分重復的內(nèi)容;2、對于每一頁新內(nèi)容,我們在點擊頁碼鏈接的時候再動態(tài)向服務器獲取數(shù)據(jù),服務器根據(jù)所請求的頁碼返回特定頁的內(nèi)容,替換掉當前顯示的頁面數(shù)據(jù),這樣可以 減少網(wǎng)絡帶寬的使用,畢竟每次只返回一頁的內(nèi)容;3、對于數(shù)據(jù)更新頻繁的分頁系統(tǒng),就按照上面的辦法每次獲取新數(shù)據(jù);而對于不是很頻繁的數(shù)據(jù),我們提供一種客戶端緩存機制來加快響應速度和減輕服務器壓 力:通過一個全局的cache數(shù)組來存放服務器端之前返回的數(shù)據(jù),在切換頁面的時候,先查詢緩存,如果沒有命中,再向服務器發(fā)起異步請求,當響應到達的時 候,也會將此次數(shù)據(jù)存入緩存以供使用。按照上面的分析,可以發(fā)現(xiàn)這兩種數(shù)據(jù)獲取方式的模板有很多相似的地方,不同的只是緩存與否,我們可以將他們抽象成同一個類來實現(xiàn),下面是 javascript代碼,我將在后面就一些需要注意的地方做詳細講解: js 代碼1. /* 2. *異步模板,每次請求一個頁面,并緩存瀏覽過的頁面(可選) 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ù),設置初始顯示頁面以及是否緩存頁面 12. this.option=Object.extend(isCache:true,option); 13. if(this.option.isCache) 14. this.cache=newArray();/緩存數(shù)組; 15. 16. , 17. 18. /實 現(xià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類的同名方法,向頁面添加分頁導航 27. addNavigation:mixin.addNavigation,/方法劫 持,重用addNavigation添加分頁導航 28. 29. /導 航鏈接點擊事件處理函數(shù),切換頁面內(nèi)容,同時改變導航鏈接樣式(突出顯示當前頁) 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ù)緩存標志切換頁面內(nèi)容 41. _displayPage:function(link) 42. varpage=link.firstChild.nodeValue; 43. /如果是第一頁,且進行緩存的話,直接切換頁面元素的可見性 44. if(page=1&this.cache) 45. $(default).className=; 46. $(swap).className=hidden; 47. 48. /否 則,根據(jù)緩存標志,切換顯示其它頁(包括非緩存的默認頁) 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)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論