閑話部分
最近閑著實在無聊,就做了點小東西練練手,由于原來一直在用aspNetPager進行分頁,而且也進行了深度的定制與原有系統整合的也不錯,不過畢竟是用別人的,想著看自己能試著做出來不能,后臺的分頁插件已經有比較成熟的了,那就自己試著寫一個前臺分頁吧。
話不多說,先上效果圖:
優點與缺點
來說說優缺點吧,首先AspNetPager是后臺分頁控件,所以在向客戶端回傳HTML文檔之前生成HTML階段 就會把分頁代碼生成完畢,然后回傳,而JS是前端代碼,就是HTML文檔在服務器組織完畢往客戶端傳送完畢之后才登上舞臺?;谏鲜龅膮^別,很容易總結出下面的優缺點:
優點:
1,輕量級,引入JS即可,十分方便部署與使用。
2,與后臺程序語言無關,可以在任何語言平臺上使用。
3,減少服務器負擔,減少傳輸成本,加快響應速度,改善用戶體驗。
4,前端代碼沒有被編譯,方便維護和管理。
缺點:
1,不支持SEO優化。
2,需要單獨編寫接口。
基本思路
1,我們需要通過一些參數如:記錄總條數(itemCount)、每頁條數(pageSize)來計算總共可以分的頁數(pageCount),itemCount需要通過請求數據來獲取,而pageCoun則需要通過用戶來指定。
2,我們需要知道當前是在第幾頁(currPage)。當頁面首次加載的時候默認為1,用戶也可以指定默認加載時處在第幾頁上。當翻頁時就會獲得一個新的currPage。
3,有了這些我們似乎是可以開始工作了,首頁 尾頁很好解決,首頁頁碼永遠為1,而尾頁頁碼永遠為pageCount,上一頁 下一頁也可以解決,上一頁為 currPage-1 ,下一頁為 currPage+1。似乎很完美,不過不要忘了,上一頁頁碼為currPage-1只能是 在currPage>1的時候,而下一頁頁碼為currPage+1則只能是在currPage<pageCount的時候,我想你一定知道為什么,所以在這里要判斷一下。
4,通過currPage和pageSize,我們可以很輕松的計算出當前顯示的記錄為第幾條~第幾條,前面也獲取到了pageCount,pageSize等數據,因此可以拼接字符串,來顯示分頁信息
信息顯示例如: 共12條 第1/4頁 第1~3條 3條/頁
5,重頭戲來了,對于中間頁碼部分的處理。簡單處理的話很好辦,從1到pageCount依次排列,似乎就可以了,但是不要忘了,假如你這個列表有幾十頁甚至上百頁,那這樣排列顯然不夠優雅,那么我們需要另外一個參數,那就是中間顯示頁碼的個數(showPageCount),當頁碼很多的時候,最多只顯示 2×showPageCount+1個頁碼。你一定會問,為什么是 2×showPageCount+1,而不是showPageCount。原因是我這里為了判斷方便,showPageCount的含義為,當前頁面左右兩邊出現的頁碼個數。
例如:總共有10頁,當前頁為5,showPageCount為2,
那么頁碼則顯示為: 首頁 上一頁 3 4 5 6 7 下一頁 尾頁
意外情況:如果左邊或者右邊顯示不夠showPageCount的頁碼數量,為了保持頁碼顯示量是一定的,則會從另外一側補全。
例如:總共10也,當前頁面為2,showPageCount為4,左側只有1個頁面可以顯示,則從右側補全,
頁碼顯示為: 首頁 上一頁 1 2 3 4 5 6 7 8 9 下一頁 尾頁
6,再在最后設置一個 Input 和 A 標簽用作轉到指定頁面功能。
7,到此為止,我們只需要把上面的各個步驟 分別拼接字符串 輸出到頁面上就OK了,但是,還有一個重要話題沒有討論,目前為止,我們只是實現了分頁的結構,但是功能似乎還沒有實現。實現功能有兩種方式:
(1),給頁碼標簽的 href 屬性綁定對應的鏈接,后面跟參數如 href="Article.aspx?page=2" 點擊之后帶上頁碼參數2 去請求第二頁的信息。我們在后臺程序通過Request到page的值,給Repeater控件做相應的綁定也好,輸出字符串也好,都可以實現功能。
(2),添加 onclick 屬性,并綁定函數,通過函數做 Ajax 請求,通過響應的函數(可以是鍵值對,也可以是HTML字符串),來給替換當前頁面上的列表,產生新的列表,同時分頁的當前頁也需要更換成對應的當前頁,完成之后效果實現。
第一種很簡單,在拼接字符串的時候,順帶這把 href 屬性寫了就完事,這里不做過多敘述,關鍵說第二種,由于采用了ajax 在翻頁的時候做請求,拿到響應數據,改寫列表容器,既然如此,那么我們頁面首次加載獲取pageCount的時候,也可以順便把列表給綁定了。簡單總結起來大致流程如下:
A:頁面加載——收集請求參數和查詢條件(currPage為1),ajax請求,拿到響應信息(至少包括 itemCount 和 列表信息),通過回調函數,用itemCount 計算分頁的各項參數 生成分頁,通過列表信息,生成列表,完成初次加載。
B:翻頁事件——再次收集求情和查詢條件(currPage為當前頁碼),ajax請求,拿到響應信息(至少包括 itemCount 和 列表信息),通過回調函數,用itemCount 計算分頁的各項參數 拼接字符串改寫分頁容器內容,通過列表信息,改寫列表容器內容,完成初次加載。
我們可以直觀的發現,A事件和B事件,流程基本一致,唯一的區別就是 currPage的值不同,因此我們可以做一個類似于遞歸的方法(不算嚴格意義上的遞歸),我們寫一個 Load() 函數來用作 列表和分頁的首次加載,在容器值被改寫過之后,需要給 頁碼的 onclick 事件綁定函數,此時我們綁用本身這個Load()函數,所以每次點擊后仍然綁定的是Load()方法。這樣一段代碼,就可以在兩個事件中重復使用了。
8,關于傳參,剛才我們一直提到 手機請求參數和查詢條件,例如:容器ID,列表所屬分類ID,每頁條數,URL格式等等。 那么我們究竟如何把參數傳遞到方法中去?想實現目的,以下幾種方式都可以。
A:聲明全局變量,在函數中調用,但是這種方式會造成大量的變量冗余,同時 Load()函數需要 傳入大量的參數,如:Load(agrA,agrB , agrC , agrD , agrE , agrF ... ),不可取。
B : 傳入Json字符串,通過鍵值對的方式傳入參數,這種方法,雖說只有一個參數,但是在編寫的時候過于繁瑣,而且無法指定默認值,或者可選項,需要在JS中重新判斷,不可取。
C : 如果說上面兩個都PASS掉了,那么你一定知道接下來要做什么了,沒錯!javaScript是一門面向對象的語言,雖然經常被人們忽略,但是他是可以使用對象和面向對象的一些編程方式的,因此我們可以建立分頁的實體類,然后每次調用的時候,new() 出來一個新的對象,這樣既可以保證同一個頁面有多個分頁的時候互不沖突,同時又可以優雅地指定我們的屬性值,還可以通過類似于構造函數的方式進行默認值的初始化。
調用方式
引入jquery、ruguoPager和CSS:
1 <script src="js/jquery-1.11.1.min.js"></script>2 <script src="js/ruguoPager-1.0.js"></script>3 <link rel="stylesheet" href="css/ruguoPager.css">
編寫html結構指定好ID:
<div class="ctn"> <div class="news" name="pager1"> <ul class="list" id="news_ul"></ul> <div class="box_height_1000px"></div> <div class="ruguoPager_red" id="pager1"></div> </div></div>
在HTML頁面上加入script標簽 指定對象參數 進行分頁
1 <script> 2 var pager = new ruguoPager(); 3 pager.pagerType="ajax"; 4 pager.objName="pager"; 5 pager.pagerID="pager1"; 6 pager.listID="news_ul"; 7 pager.toPoint="pager1" 8 pager.showPageSize=4; 9 pager.pageSize=3;10 pager.currPage=1;11 pager.typeID=63;12 pager.pagerUrl="news/list_{ruguo:pageNum}.html";13 pager.itemStr="<li><a href='news/detail_{ruguo:id}.html'>{ruguo:title}</a>[{ruguo:datetime}]</li>";14 pager.ajaxUrl="ajax/getArticleList.ashx";15 ruguoPagerLoad(pager);16 </script>
參數列表(參數名,參數含義,可選值,必須)
pagerType | 初始化類型 | 'ajax' or ' url' | |
objName | 對象名 | string | * |
pagerID | 分頁容器ID | string | * |
listID | 列表容器ID | string | - |
currPage | 當前頁 | int | |
pageSize | 每頁條數 | int | |
itemCount | 記錄總條數 | int | |
showPageSize | 顯示頁碼數 | string | |
pagerUrl | 分頁路徑格式 | string | - |
typeID | 列表類別ID | int | |
titLen | 列表標題字數 | int | |
itemStr | 列表標題格式 | string | |
ajaxUrl | ajax請求地址 | string | * |
toPoint | 錨點標記 | string | |
isShowFirst | 是否顯示首頁按鈕 | 'always' , 'auto' , 'none' | |
isShowPReviousPage | 是否顯示上一頁按鈕 | 'always' , 'auto' , 'none' | |
isShowNextPage | 是否顯示下一頁按鈕 | 'always' , 'auto' , 'none' | |
isShowLastPage | 是否顯示尾頁按鈕 | 'always' , 'auto' , 'none' | |
isShowPages | 是否顯示頁碼按鈕 | 'always' , 'auto_0' , 'auto_1' , 'none' | |
isShowGo | 是否顯示跳轉 | 'always' , 'auto' , 'none' |
總結
在編寫插件的過程中,遇到了很多實際的問題,并一個一個的加以解決,得到了不少心得,在這里總結一下。
1,類的使用
在寫Javascript的時候,尤其是在Jquery被廣泛使用知乎,我們往往會在頁面中羅列一個接一個的函數, 但是有時候我們嘗試著使用一下類,會使得代碼變得更加優雅。在寫這個插件之前,只知道JS可以寫類,實例化對象,但是究竟怎么用,卻從來沒試過,甚至怎么定義一個類都不知道。通過本例,初步了解了JS中類的基本使用方式。
2,函數的重載
在解決 Load() 函數重用問題上,我想使用重載,但是根據自己的猜想,試了一下沒有成功,經過查資料發現正確的使用方式。在C#中我們知道,方法可以重載,要求方法名相同,返回類型或者形參類型、數量不同。然而針對于JS來說,是沒有重載一說的,因為JS是若類型語言,在調用方法的時候,根本沒有參數類型以及返回類型一說。雖然如此,好在參數個數還是可以檢測到的,所以根據這一特點,可以進行模擬重載,但是注意并非真正重載。
3,全局變量
在寫插件時候,第一次實例化的對象,并把對象的各個屬性通過AJAX傳遞,拿到了響應信息,完成了分頁和列表的首次加載。當點擊分頁時候,需要再次執行同樣的操作,因此需要再次進行實例化對象,這樣一來方法就無法復用,意味著,頁面上每多一個分頁,就需要copy一份js用作不同的 在點擊分頁時候的實例化。所以我就在想,點擊分頁事件時候的對象,與第一次的對象不一樣的僅僅只是當前頁碼而已,所以通過對象本身包含對象名的方式,在綁定分頁事件方法時,把對象名當作參數放在了Load()方法中,并多了一個當前頁參數,通過模擬重載 順利完成Load()方法的復用。雖然JS沒有非常嚴格的訪問級別,但是我想寫在文檔流中的變量應該都是全局變量,在初次實例化時候的對象同樣也是,所以綁定分頁事件方法中的參數 應該是可以調用到 全局對象的,結果證明我的猜想完全正確。
4,ajax分頁用戶體驗
通過ajax分頁時候會有一個問題,那就是點擊分頁之后,由于頁面并不刷新或者跳轉,而是直接修改了頁面容器的內容,所以頁面會保持在列表最下方不動,每次點擊完分頁,需要手動把網頁撥回到最頂部,然后再慢慢往下翻著看,很麻煩,所以我做了一個本地描點,在初次實例化的時候需要傳錨點ID,點擊之后,返回到錨點處。
效果類似于騰訊新聞列表的效果:http://news.QQ.com/top_index.shtml
5,jquery綁定事件傳參
在寫插件過程中,起初用到了需要往jquery綁定事件中傳參,由于習慣了使用 例如 $("a").click(function(){ alert("hello world"); });這樣的綁定方式,所以如何往click事件所執行的方法中傳入參數一時間十分苦惱,后來經過查詢,知道了可以使用 這樣的方式進行傳參:$("a").bind("click",{myValue:hello world},function(event){ alert(event.data.myValue) }); ,雖然后來有了更好的方式,無需傳參了,但是也算是一個不小的收獲吧。
6,當json遇上HTML
json是我們網上常用的傳遞數據的格式,而且js可以很輕松的解析,但是由于json遇到html中的 尖括號(< >)會出現問題,無法正確返回,因此,我們需要響應數據的時候進行HTML編碼,在回調函數中,對拿到的編碼后的字符串進行反編碼。另外順帶提一下,在使用eval()解析數據的時候最好里面再套上一個"("+data+")",原因是json中的大括號會影響js的結構。
存在的問題
1,代碼重用部分,其實并沒有把url與ajax的方式完全區分開,由于當使用url的時候,初次加載列表和 總頁數 可以通過后臺綁定出來,因此在點擊分頁的時候,就無需再次請求數據,僅僅進行前臺的計算即可,可以減少一次請求。
2,代碼寫的比較亂,大伙湊合著看吧。
3,本人才疏學淺,寫代碼純屬業余興趣愛好,還望跟各位大神多多學習,存在的問題或者是更好的解決方案,還請不吝賜教,幫助我完善插件,網上成熟的插件有很多,本人獻丑不敢說分享勞動成果工,只能說在學習中遇到的問題拿來給暫時還沒有遇到的人,少走一些彎路,同時滿足一下自己小小的成就感,僅此而已。
代碼與文章都是博主辛苦一點一點碼出來的,請尊重博主辛勤勞動,歡迎轉載,轉載請注明出處,更多交流請關注 D調碼農的筆記簿 http://www.49028c.com/webconfig
最后放出下載地址
相關文檔下載:http://files.VEVb.com/webconfig/ruguoPager.rar
新聞熱點
疑難解答