背景
找到一款自認為不錯的分頁組件,《js版的QuickPager分頁控件 V2.0》,想下載完整的資源,js/css等,不過找了一會,沒找到,聯系博主也沒有回復。那直接看了頁面引用了js文件,下載下來改寫了一下,同時借此機會進一步掌握封裝jquery組件。雖說有重復造輪子之嫌,不過只有重復造了輪子,才能更好的掌握。不是曾經有位大神說過,“看再多的框架,不如親自動手寫一個框架。。。”
先上個圖看看效果。
插件實現
先看看調用方式。
$(".pager").pagination({ recordCount: 3211, //總記錄數 pageSize: 10, //一頁記錄數 onPageChange: function (pageIndex) { document.title = pageIndex; } });
這個是插件的初始化方法。完整的分頁控件html元素代碼如下:
<span style="cursor: pointer;">共<span name="recordCount" style="color: Red;">102</span>條記錄</span> <span style="cursor: pointer;">第<span name="pageIndex" style="color: Red;">1</span>/<span name="pageCount" style="color: Red;">11</span>頁</span> <span style="cursor: pointer;">每頁<span name="pageSize" style="color: Red;">10</span>條記錄</span> <span name="first" class="disabled" style="cursor: default;">首頁</span> <span name="prev" class="disabled" style="cursor: default;">上一頁</span> <span name="next" class="" style="cursor: pointer;">下一頁</span> <span name="last" class="" style="cursor: pointer;">末頁</span> <input name="goNum" class="cssTxt" type="text" size="1"> <span name="go" style="cursor: pointer;">GO</span>
而在實際的過程中,可能需求不同,有點只需要顯示分頁按鈕,有的不需要顯示 總共多少頁,總有多少條記錄,或者有的只需要顯示分頁導航數字。那么在定義分頁元素的時候,可以自定義,如果未定義任何元素,則插件自動填充完整的html代碼至div中。
初始化的時候會遍歷內部的元素,找到對應的按鈕添加事件。在按鈕的事件處理完畢后,會判斷是否有導航頁的容器,如果存在,則根據當前頁碼基於某種算法生成幾個頁碼導航欄。大致就是這些內容了。
此外,樓主還想添加一個方法,直接切換到指定的頁碼。在這里的時候遇到一個問題,之前在插件內部定義了一個變量來存儲分頁按鈕的相關對象,后來發現當想在頁面上實例化多個分頁插件的時候,遇到問題了,變量公用了有沖突。
於是增加了一個私有方法,將分頁所有實現放置在該方法中,分頁對象最后保存在this對象的屬性上,便於后面可以訪問,以便於增加事件處理。
(function($){ $.initPagination = function(info){ ... } $.fn.pagination = function (pagerInfo) { this.each(function () { $.initPagination.call(this, pagerInfo); }); } $.fn.PageChanged = function (pageIndex) { this[0].pager && this[0].pager.PageChanged.call(this, pageIndex); }; }(jQuery));
pager對象就是存儲在分頁容器中,包含了分頁的所有處理。
寫到這里,感覺進一步加強了寫jquery插件的能力。
完整實現如下:
(function ($) { $.initPagination = function (info) { var $div = $(this); var pager = { $first: null,//首頁按鈕 $prev: null,//上一頁按鈕 $nav: null,//導航區按鈕 $next: null,//下一頁按鈕 $last: null,//末頁按鈕 $goNum: null,//翻頁文本輸入框 $go: null,//翻頁按鈕 $recordCount: null,//總行數 $pageIndex: null,//當前頁號 $pageCount: null,//總頁數 $pageSize: null,//頁碼數 Init: function () { //初始化控件 緩存 $div.find("[name]").each(function () { var name = $(this).attr("name"); if (name && name.length) { pager["$" + name] = $(this); } }); pager.SetPageUI(); }, //創建導航 CreateNavi: function () { //頁號導航 if (!pager.$nav) return; var n1 = "<a class=\"navi\">{text}</a>"; var navi = pager.$nav; navi.empty(); var i; var temp = ""; var s1; var s2; var naviCount2 = (info.naviCount % 2) == 1 ? info.naviCount / 2 | 0 : info.naviCount / 2; if ((info.thisPageIndex - naviCount2) < 1) { s1 = 1; s2 = info.naviCount; } else if ((info.thisPageIndex + naviCount2) >= info.pageCount) { s1 = info.pageCount - info.naviCount + 1; s2 = info.pageCount; if (s1 < 1) s1 = 1; } else { s1 = info.thisPageIndex - naviCount2; s2 = info.thisPageIndex + naviCount2; if (s2 > info.pageCount) s2 = info.pageCount; } if (s2 > info.pageCount) s2 = info.pageCount; if (s1 >= 2) { temp = n1.replace("{text}", 1); navi.append(temp); } if (s1 >= 3) { temp = n1.replace("{text}", "…"); navi.append(temp); } for (i = s1; i <= s2; i++) { //當前頁 temp = n1.replace("{text}", i == info.thisPageIndex ? "<font style=\"color:#999\">" + i + "</font>" : i); navi.append(temp); } if (s2 <= info.pageCount - 2) { temp = n1.replace("{text}", "…"); navi.append(temp); } if (s2 <= info.pageCount - 1) { temp = n1.replace("{text}", info.pageCount); navi.append(temp); } //注冊事件 var naviA = navi.find("a"); naviA.each(function (j) { $(this).on('click', function () { info.beforePageIndex = info.thisPageIndex; if (this.innerHTML == "…") { var a1 = naviA[j - 1]; if (a1.innerHTML == "1") { //前面的,取后面的作為頁號 a1 = naviA[j + 1]; info.thisPageIndex = $(a1).text() * 1 - 1; } else { //后面的,取前面的作為頁號 a1 = naviA[j - 1]; info.thisPageIndex = $(a1).text() * 1 + 1; } } else { info.thisPageIndex = $(this).text(); } //頁碼未變更則不觸發事件 if (info.beforePageIndex == info.thisPageIndex) return; pager.PageChanged(); }); }); }, //設置UI SetPageUI: function () { if (info.pageCount == -1) { //計算總頁數 info.pageCount = info.recordCount % info.pageSize === 0 ? info.recordCount / info.pageSize : parseInt(info.recordCount / info.pageSize) + 1; } pager.$recordCount && pager.$recordCount.html(info.recordCount); pager.$pageIndex && pager.$pageIndex.html(info.thisPageIndex); pager.$pageCount && pager.$pageCount.html(info.pageCount); pager.$pageSize && pager.$pageSize.html(info.pageSize); pager.$goNum && pager.$goNum.val(info.thisPageIndex); $div.find("span").css("cursor", "pointer"); switch (parseInt(info.thisPageIndex)) { case 1: //第一頁 pager.$first && pager.$first.hide().css("cursor", "default"); pager.$prev && pager.$prev.hide().css("cursor", "default"); pager.$next && pager.$next.show().css("cursor", "pointer"); pager.$last && pager.$last.show().css("cursor", "pointer"); break; case info.pageCount: //最后一頁 pager.$first && pager.$first.show().css("cursor", "pointer"); pager.$prev && pager.$prev.show().css("cursor", "pointer"); pager.$next && pager.$next.hide().css("cursor", "default"); pager.$last && pager.$last.hide().css("cursor", "default"); break; default: //不是第一頁、最后一頁 pager.$first && pager.$first.show().css("cursor", "pointer"); pager.$prev && pager.$prev.show().css("cursor", "pointer"); pager.$next && pager.$next.show().css("cursor", "pointer"); pager.$last && pager.$last.show().css("cursor", "pointer"); break; } }, //設置缺省設置 SetDefaultInfo: function (pSet) { var defaultSetting = { recordCount: -1, //總記錄數 pageSize: 10, //一頁記錄數 pageCount: -1, //總頁數,不用設置,根據上兩個條件自動計算 thisPageIndex: 1, //當前頁號 beforePageIndex: 1, //上一次的頁號 //lastPageIndex: 0, //最后一頁的頁號,自動計算 naviCount: 7, //頁號導航的數量 isUseRecordCount: true, //是否使用緩存的總記錄數 //分頁控件模板的路徑和文件名 templetPath: "pager", }; return $.extend(defaultSetting, pSet); }, //注冊翻頁的事件,不包括頁號導航 RegPagerEvent: function () { pager.$first && pager.$first.on('click', function () { if (info.thisPageIndex != 1) { addEvent("a"); } }); pager.$prev && pager.$prev.on('click', function () { if (info.thisPageIndex != 1) { addEvent("-"); } }); pager.$next && pager.$next.on('click', function () { if (info.thisPageIndex != info.pageCount) { addEvent("+"); } }); pager.$last && pager.$last.on('click', function () { if (info.thisPageIndex != info.pageCount) { addEvent("z"); } }); pager.$go && pager.$go.on('click', function () { addEvent("go"); }); var addEvent = function (kind) { info.beforePageIndex = info.thisPageIndex; switch (kind) { case "a": info.thisPageIndex = 1; break; //首頁 case "z": info.thisPageIndex = info.pageCount; break; //末頁 case "+": info.thisPageIndex = info.thisPageIndex * 1 + 1; break; //下頁 case "-": info.thisPageIndex = info.thisPageIndex * 1 - 1; break; //上頁 case "go": info.thisPageIndex = pager.$goNum.val(); break; //go } pager.PageChanged(); }; }, //頁面變更事件 PageChanged: function (pIndex) { if (pIndex) info.thisPageIndex = pIndex; //如果頁碼錯誤 則中斷 if (isNaN(info.thisPageIndex)) { alert("頁碼不正確"); return; } info.thisPageIndex = parseInt(info.thisPageIndex); //判斷范圍 if (info.thisPageIndex > info.pageCount) info.thisPageIndex = info.pageCount; if (info.thisPageIndex < 1) info.thisPageIndex = 1; info.onPageChange && info.onPageChange.call(info, info.thisPageIndex); pager.SetPageUI(); //重新設置UI pager.CreateNavi(); //克隆 //var tmpdiv = info.pageTurnDivIDs.split(","); //var pageHtml = $("#" + tmpdiv[0]).clone(true); //for (var i = 1; i < tmpdiv.length; i++) { // $("#" + tmpdiv[i]).html(pageHtml); //} } }; //設置默認值 info = pager.SetDefaultInfo(info); //如果模板沒有自定義 則自動填充 var html = $div.html(); if (!/\w+/.test(html)) { html = '<span style="cursor: pointer;">共<span name="recordCount" style="color: Red;">102</span>條記錄</span><span style="cursor: pointer;"> 第<span name="pageIndex" style="color: Red;">1</span>/<span name="pageCount" style="color: Red;">11</span>頁</span><span style="cursor: pointer;"> 每頁<span name="pageSize" style="color: Red;">10</span>條記錄 </span><span name="first" class="disabled" style="cursor: default;">首頁</span><span name="prev" class="disabled" style="cursor: default;">上一頁 </span><span name="nav" style="cursor: pointer;"><a class="navi"><span style="color: #999">1</span></a></span><span name="next" class="" style="cursor: pointer;">下一頁 </span><span name="last" class="" style="cursor: pointer;">末頁 </span><input name="goNum" class="cssTxt" type="text" size="1"><span name="go" style="cursor: pointer;"> GO</span>'; $div.html(html); } //增加樣式 if (!$div.hasClass("pager")) $div.addClass("pager"); //初始化 緩存控件 pager.Init(); //注冊事件(僅限上一頁、下一頁、首頁、末頁,不包括頁號導航) pager.RegPagerEvent(); //創建導航 並增加導航事件 pager.CreateNavi(); this.pager = pager; return this; } $.fn.pagination = function (pagerInfo) { this.each(function () { $.initPagination.call(this, pagerInfo); }); } $.fn.PageChanged = function (pageIndex) { this[0].pager && this[0].pager.PageChanged.call(this, pageIndex); }; }(jQuery));
插件目的
插件不是為了模仿那些grid組件,而是提供一個分頁導航的功能,類似當初做Asp.Net的時候用的經典插件,AspNetPager。控件旨在提供分頁按鈕以及導航UI的控制,而具體的處理邏輯,如顯示table數據,則只用監聽其PageChanged事件即可。