閒話部分 css
最近閒着實在無聊,就作了點小東西練練手,因爲原來一直在用AspNetPager進行分頁,並且也進行了深度的定製與原有系統整合的也不錯,不過畢竟是用別人的,想着看本身能試着作出來不能,後臺的分頁插件已經有比較成熟的了,那就本身試着寫一個前臺分頁吧。html
話很少說,先上效果圖:前端
優勢與缺點jquery
來講說優缺點吧,首先AspNetPager是後臺分頁控件,因此在向客戶端回傳HTML文檔以前生成HTML階段 就會把分頁代碼生成完畢,而後回傳,而JS是前端代碼,就是HTML文檔在服務器組織完畢往客戶端傳送完畢以後才登上舞臺。基於上述的區別,很容易總結出下面的優缺點:web
優勢:ajax
1,輕量級,引入JS便可,十分方便部署與使用。編程
2,與後臺程序語言無關,能夠在任何語言平臺上使用。json
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.cnblogs.com/webconfig
最後放出下載地址