项目中我们常会用到分页控件,当然有很多好用的JQuery分页插件,但未必能满足我们的特定需求,所以有时我们要做一些改动,
此篇文章我们就对jQuery pager plugin 做一个扩展。
1. JQuery.pager.js(当总页码数超出9页时,增加快速跳转功能,可输入的最大值为总页码数)
1 /* 2 * jQuery pager plugin 3 * Version 1.0 (12/22/2008) 4 * @requires jQuery v1.2.6 or later 5 * 6 * Example at: http://jonpauldavies.github.com/JQuery/Pager/PagerDemo.html 7 * 8 * Copyright (c) 2008-2009 Jon Paul Davies 9 * Dual licensed under the MIT and GPL licenses: 10 * http://www.opensource.org/licenses/mit-license.php 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * Read the related blog post and contact the author at http://www.j-dee.com/2008/12/22/jquery-pager-plugin/ 14 * 15 * This version is far from perfect and doesn't manage it's own state, therefore contributions are more than welcome! 16 * 17 * Usage: .pager({ pagenumber: 1, pagecount: 15, buttonClickCallback: PagerClickTest }); 18 * 19 * Where pagenumber is the visible page number 20 * pagecount is the total number of pages to display 21 * buttonClickCallback is the method to fire when a pager button is clicked. 22 * 23 * buttonClickCallback signiture is PagerClickTest = function(pageclickednumber) 24 * Where pageclickednumber is the number of the page clicked in the control. 25 * 26 * The included Pager.CSS file is a dependancy but can obviously tweaked to your wishes 27 * Tested in IE6 IE7 Firefox & Safari. Any browser strangeness, please report. 28 */ 29 (function ($) { 30 31 $.fn.pager = function (options) { 32 33 var opts = $.extend({}, $.fn.pager.defaults, options); 34 var pgcount = getPageCount(opts.recordcount, opts.pagesize); 35 return this.each(function () { 36 37 // empty out the destination element and then render out the pager with the supplied options 38 $(this).empty().append(renderpager(parseInt(opts.pagenumber), pgcount, opts.recordcount, opts.buttonClickCallback, 39 opts.firsttext, opts.prevtext, opts.nexttext, opts.lasttext, opts.recordtext, opts.gotext)); 40 41 // specify correct cursor activity 42 $(' li', this).mouseover(function () { document.body.style.cursor = "pointer"; }).mouseout(function () { document.body.style.cursor = "auto"; }); 43 }); 44 }; 45 46 function getPageCount(totalCount, pageSize) { 47 var pageCount = 0; 48 pageCount = parseInt(totalCount / pageSize); 49 if (totalCount % pageSize > 0) { 50 pageCount++; 51 } 52 return pageCount; 53 } 54 55 // render and return the pager with the supplied options 56 function renderpager(pagenumber, pagecount, recordcount, buttonClickCallback, firsttext, prevtext, nexttext, lasttext, recordtext, gotext) { 57 58 // setup $pager to hold render 59 var $pager = $('<ul class="pages"></ul>'); 60 61 // add in the previous and next buttons 62 $pager.append(renderButton('first', firsttext, pagenumber, pagecount, buttonClickCallback)).append(renderButton('prev', prevtext, pagenumber, pagecount, buttonClickCallback)); 63 64 // pager currently only handles 10 viewable pages ( could be easily parameterized, maybe in next version ) so handle edge cases 65 var startPoint = 1; 66 var endPoint = 9; 67 if (pagenumber > pagecount) { 68 pagenumber = pagecount; 69 } 70 if (pagenumber > 4) { 71 startPoint = pagenumber - 4; 72 endPoint = pagenumber + 4; 73 } 74 75 if (endPoint > pagecount) { 76 startPoint = pagecount - 8; 77 endPoint = pagecount; 78 } 79 80 if (startPoint < 1) { 81 startPoint = 1; 82 } 83 84 // loop thru visible pages and render buttons 85 for (var page = startPoint; page <= endPoint; page++) { 86 87 var currentButton = $('<li class="page-number">' + (page) + '</li>'); 88 89 page == pagenumber ? currentButton.addClass('pgCurrent') : currentButton.click(function () { buttonClickCallback(this.firstChild.data); }); 90 currentButton.appendTo($pager); 91 } 92 93 // render in the next and last buttons before returning the whole rendered control back. 94 $pager.append(renderButton('next', nexttext, pagenumber, pagecount, buttonClickCallback)).append(renderButton('last', lasttext, pagenumber, pagecount, buttonClickCallback)); 95 if (pagecount > 9) { 96 $pager.append('<li class="pgText"><input tyle="text" class="iptGo" /><span class="spGo">' + gotext + '</span></li>'); 97 $('.iptGo', $pager).change(function () { 98 var num = parseInt($(this).val()); 99 if (num && num > 0) { 100 if (num > pagecount) { 101 num = pagecount; 102 } 103 $(this).val(num); 104 } 105 else { 106 $(this).val(''); 107 } 108 }).keyup(function () { $(this).change(); }); 109 $('.spGo', $pager).click(function () { 110 var num = $('.iptGo', $pager).val(); 111 if (num != '') { 112 buttonClickCallback(num); 113 } 114 }); 115 } 116 if (recordtext != '') { 117 $pager.append('<li class="pgText">' + recordtext.replace(/\{0\}/g, pagecount).replace(/\{1\}/g, recordcount) + '</li>'); 118 } 119 return $pager; 120 } 121 122 // renders and returns a 'specialized' button, ie 'next', 'previous' etc. rather than a page number button 123 function renderButton(buttonLabel, buttonText, pagenumber, pagecount, buttonClickCallback) { 124 125 var $Button = $('<li class="pgNext">' + buttonText + '</li>'); 126 127 var destPage = 1; 128 129 // work out destination page for required button type 130 switch (buttonLabel) { 131 case "first": 132 destPage = 1; 133 break; 134 case "prev": 135 destPage = pagenumber - 1; 136 break; 137 case "next": 138 destPage = pagenumber + 1; 139 break; 140 case "last": 141 destPage = pagecount; 142 break; 143 } 144 145 // disable and 'grey' out buttons if not needed. 146 if (buttonLabel == "first" || buttonLabel == "prev") { 147 pagenumber <= 1 ? $Button.addClass('pgEmpty') : $Button.click(function () { buttonClickCallback(destPage); }); 148 } 149 else { 150 pagenumber >= pagecount ? $Button.addClass('pgEmpty') : $Button.click(function () { buttonClickCallback(destPage); }); 151 } 152 153 return $Button; 154 } 155 156 // pager defaults. hardly worth bothering with in this case but used as placeholder for expansion in the next version 157 $.fn.pager.defaults = { 158 pagenumber: 1, 159 recordcount: 0, 160 pagesize: 10, 161 firsttext: 'first',//显示的第一页文本 162 prevtext: 'prev',//显示的前一页文本 163 nexttext: 'next',//显示的下一页文本 164 lasttext: 'last',//显示的最后一页文本 165 gotext: 'go',//显示的快速跳转文本 166 recordtext: ''//显示记录数,为空时不显示,否则按照占位符显示文本,{0}表示总页数,{1}表示总记录数 167 }; 168 169 })(jQuery);
2. JQuery中对应的CSS样式
1 .jqpager ul.pages { 2 display: block; 3 border: none; 4 text-transform: uppercase; 5 margin: 2px 0 15px 2px; 6 padding: 0; 7 } 8 9 .jqpager ul.pages li { 10 list-style: none; 11 float: left; 12 border: 1px solid #ccc; 13 text-decoration: none; 14 margin: 0 5px 0 0; 15 padding: 5px; 16 } 17 18 .jqpager ul.pages li:hover { 19 border: 1px solid #003f7e; 20 } 21 22 .jqpager ul.pages li.pgEmpty { 23 border: 1px solid #aaa; 24 color: #aaa; 25 cursor: default; 26 } 27 28 .jqpager ul.pages li.pgText { 29 border: none; 30 cursor: default; 31 } 32 33 .jqpager ul.pages li.page-number { 34 min-width: 15px; 35 text-align: center; 36 } 37 38 .jqpager ul.pages li.pgCurrent { 39 border: 1px solid #003f7e; 40 color: #000; 41 font-weight: 700; 42 background-color: #eee; 43 } 44 45 .jqpager input.iptGo { 46 width: 30px; 47 border: 1px solid #ccc; 48 margin: -2px 0px 0px 0px; 49 height: 18px; 50 vertical-align: middle; 51 } 52 53 .jqpager span.spGo { 54 cursor: pointer; 55 margin-left: 2px; 56 }
3. 为了更方便的获取当前页码及对当前url参数做处理,封装了一个对URL做处理的小插件 simple.url.js
1 /* File Created: 十二月 25, 2012 */ 2 var simpleUrl = {}; 3 4 simpleUrl.parseURL = function (url) { 5 ///<summary>分析url</summary> 6 ///<param name="网址URL" type="String"> 7 var a = document.createElement('a'); 8 a.href = url; 9 return { 10 source: url, 11 protocol: a.protocol.replace(':', ''), 12 host: a.hostname, 13 port: a.port, 14 query: a.search, 15 params: (function () { 16 var ret = {}, 17 seg = a.search.replace(/^\?/, '').split('&'), 18 len = seg.length, i = 0, s; 19 for (; i < len; i++) { 20 if (!seg[i]) { continue; } 21 s = seg[i].split('='); 22 ret[s[0]] = s[1]; 23 } 24 return ret; 25 26 })(), 27 file: (a.pathname.match(/\/([^\/?#]+)$/i) || [, ''])[1], 28 hash: a.hash.replace('#', ''), 29 path: a.pathname.replace(/^([^\/])/, '/$1'), 30 relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [, ''])[1], 31 segments: a.pathname.replace(/^\//, '').split('/') 32 }; 33 34 //#region 使用示例 35 /* 36 var myURL = parseURL('http://abc.com:8080/dir/index.html?id=255&m=hello#top'); 37 w("myUrl.file = " + myURL.file) // = 'index.html' 38 w("myUrl.hash = " + myURL.hash) // = 'top' 39 w("myUrl.host = " + myURL.host) // = 'abc.com' 40 w("myUrl.query = " + myURL.query) // = '?id=255&m=hello' 41 w("myUrl.params = " + myURL.params) // = Object = { id: 255, m: hello } 42 w("myUrl.path = " + myURL.path) // = '/dir/index.html' 43 w("myUrl.segments = " + myURL.segments) // = Array = ['dir', 'index.html'] 44 w("myUrl.port = " + myURL.port) // = '8080' 45 w("myUrl.protocol = " + myURL.protocol) // = 'http' 46 w("myUrl.source = " + myURL.source) // = 'http://abc.com:8080/dir/index.html?id=255&m=hello#top' 47 48 var _newUrl = replaceUrlParams(myURL, { id: 101, m: "World", page: 1,"page":2 }); 49 50 w("<br>新url为:") 51 w(_newUrl); //http://abc.com:8080/dir/index.html?id=101&m=World&page=2#top 52 */ 53 //#endregion 54 } 55 56 simpleUrl.replaceCurrentUrl = function (newParams) { 57 var url = this.replaceUrlParams(this.parseCurrentUrl(), newParams); 58 return url; 59 } 60 61 simpleUrl.replaceUrlParams = function (myUrl, newParams) { 62 ///<summary>替换myUrl中的同名参数值,如果有同名则替换,没有同名则追加参数</summary> 63 ///<param name="myUrl" type="simpleUrl.parseURL">需要进行参数同名替换的URL</param> 64 ///<param name="newParams" type="Object">同名替换后的URL地址</param> 65 for (var x in newParams) { 66 var hasInMyUrlParams = false; 67 for (var y in myUrl.params) { 68 if (x.toLowerCase() == y.toLowerCase()) { 69 myUrl.params[y] = newParams[x]; 70 hasInMyUrlParams = true; 71 break; 72 } 73 } 74 //原来没有的参数则追加 75 if (!hasInMyUrlParams) { 76 myUrl.params[x] = newParams[x]; 77 } 78 } 79 80 var _result = myUrl.protocol + "://" + myUrl.host + ":" + myUrl.port + myUrl.path + "?"; 81 82 for (var p in myUrl.params) { 83 _result += (p + "=" + escape(unescape(myUrl.params[p])) + "&"); 84 } 85 86 if (_result.substr(_result.length - 1) == "&") { 87 _result = _result.substr(0, _result.length - 1); 88 } 89 90 if (myUrl.hash != "") { 91 _result += "#" + myUrl.hash; 92 } 93 return _result; 94 } 95 96 simpleUrl.parseCurrentUrl = function () { 97 return simpleUrl.parseURL(window.location); 98 } 99 100 simpleUrl.getQueryStringSingle = function (key, defaultVal) { 101 ///<summary>获取URL中的参数</summary> 102 ///<param name="key" type="String">参数名称; 103 /// 比如:"http://test.aspx?action=getList";getQueryStringSingle("action")得到的结果就是参数的值"getList" 104 ///</param> 105 var value = (document.location.search.match(new RegExp("(?:^\\?|&)" + key + "=(.*?)(?=&|$)")) || ['', null])[1]; 106 if (value == null) { 107 return defaultVal; 108 } 109 else { 110 value; 111 } 112 113 return unescape(value); 114 }
然后我们就可以添加以上三个文件的引用,就可以使用了。
1 $(function () { 2 //alert(simpleLauage.lang("Signin")); 3 var currentPage = simpleUrl.getQueryStringSingle("page"); 4 currentPage = (isNaN(currentPage) || currentPage == "") ? 4 : parseInt(currentPage); 5 $('#pager').pager({ 6 pagenumber: currentPage, 7 recordcount: 100, 8 pagesize: 20, 9 buttonClickCallback: function (pageclickednumber) { 10 window.location.href = "?page=" + pageclickednumber; 11 }, 12 firsttext: '首页', 13 prevtext: '前一页', 14 nexttext: '下一页', 15 lasttext: '尾页', 16 recordtext: '共{0}页,{1}条记录' 17 }); 18 });
当然,别忘了在页面上加上要显示页码的位置
1 <div class="jqpager"> 2 <div id="pager"></div> 3 </div> 4 <div class="clearfix"></div>
这样,自定义的分页样式就实现了,效果图如下:
我们也可以将此应用于Bootstarp的分页控件上,此时需要对Jquery.page.js做修改记作Jquery.page-bootstarp.js,完整代码如下:
1 /* 2 * jQuery pager plugin 3 * Version 1.0 (12/22/2008) 4 * @requires jQuery v1.2.6 or later 5 * 6 * Example at: http://jonpauldavies.github.com/JQuery/Pager/PagerDemo.html 7 * 8 * Copyright (c) 2008-2009 Jon Paul Davies 9 * Dual licensed under the MIT and GPL licenses: 10 * http://www.opensource.org/licenses/mit-license.php 11 * http://www.gnu.org/licenses/gpl.html 12 * 13 * Read the related blog post and contact the author at http://www.j-dee.com/2008/12/22/jquery-pager-plugin/ 14 * 15 * This version is far from perfect and doesn't manage it's own state, therefore contributions are more than welcome! 16 * 17 * Usage: .pager({ pagenumber: 1, pagecount: 15, buttonClickCallback: PagerClickTest }); 18 * 19 * Where pagenumber is the visible page number 20 * pagecount is the total number of pagination to display 21 * buttonClickCallback is the method to fire when a pager button is clicked. 22 * 23 * buttonClickCallback signiture is PagerClickTest = function(pageclickednumber) 24 * Where pageclickednumber is the number of the page clicked in the control. 25 * 26 * The included Pager.CSS file is a dependancy but can obviously tweaked to your wishes 27 * Tested in IE6 IE7 Firefox & Safari. Any browser strangeness, please report. 28 */ 29 (function ($) { 30 31 $.fn.pager = function (options) { 32 33 var opts = $.extend({}, $.fn.pager.defaults, options); 34 35 return this.each(function () { 36 37 // empty out the destination element and then render out the pager with the supplied options 38 $(this).empty().append(renderpager(parseInt(options.pagenumber), parseInt(options.pagecount), options.buttonClickCallback)); 39 40 // specify correct cursor activity 41 $('.pagination li').mouseover(function () { document.body.style.cursor = "pointer"; }).mouseout(function () { document.body.style.cursor = "auto"; }); 42 }); 43 }; 44 45 // render and return the pager with the supplied options 46 function renderpager(pagenumber, pagecount, buttonClickCallback) { 47 48 // setup $pager to hold render 49 var $pager = $('<ul class="pagination"></ul>'); 50 51 // add in the previous and next buttons 52 $pager.append(renderButton('<<', pagenumber, pagecount, buttonClickCallback)).append(renderButton('<', pagenumber, pagecount, buttonClickCallback)); 53 54 // pager currently only handles 10 viewable pagination ( could be easily parameterized, maybe in next version ) so handle edge cases 55 var startPoint = 1; 56 var endPoint = 9; 57 58 if (pagenumber > 4) { 59 startPoint = pagenumber - 4; 60 endPoint = pagenumber + 4; 61 } 62 63 if (endPoint > pagecount) { 64 startPoint = pagecount - 8; 65 endPoint = pagecount; 66 } 67 68 if (startPoint < 1) { 69 startPoint = 1; 70 } 71 // loop thru visible pagination and render buttons 72 for (var page = startPoint; page <= endPoint; page++) { 73 74 var currentButton = $('<li class="page-number"><a href="javascript:;">' + (page) + '</a></li>'); 75 76 page == pagenumber ? currentButton.addClass('active') : currentButton.click(function () { buttonClickCallback(this.firstChild.firstChild.data); }); 77 currentButton.appendTo($pager); 78 } 79 80 // render in the next and last buttons before returning the whole rendered control back. 81 $pager.append(renderButton('>', pagenumber, pagecount, buttonClickCallback)).append(renderButton('>>', pagenumber, pagecount, buttonClickCallback)); 82 83 return $pager; 84 } 85 86 // renders and returns a 'specialized' button, ie 'next', 'previous' etc. rather than a page number button 87 function renderButton(buttonLabel, pagenumber, pagecount, buttonClickCallback) { 88 89 var $Button = $('<li class="pgNext"><a href="javascript:;">' + buttonLabel + '</a></li>'); 90 91 var destPage = 1; 92 93 // work out destination page for required button type 94 switch (buttonLabel) { 95 case "<<": 96 destPage = 1; 97 break; 98 case "<": 99 destPage = pagenumber - 1; 100 break; 101 case ">": 102 destPage = pagenumber + 1; 103 break; 104 case ">>": 105 destPage = pagecount; 106 break; 107 } 108 // disable and 'grey' out buttons if not needed. 109 if (buttonLabel == "<<" || buttonLabel == "<") { 110 pagenumber <= 1 ? $Button.addClass('disabled') : $Button.click(function () { buttonClickCallback(destPage); }); 111 } 112 else { 113 pagenumber >= pagecount ? $Button.addClass('disabled') : $Button.click(function () { buttonClickCallback(destPage); }); 114 } 115 116 return $Button; 117 } 118 119 // pager defaults. hardly worth bothering with in this case but used as placeholder for expansion in the next version 120 $.fn.pager.defaults = { 121 pagenumber: 1, 122 pagecount: 1 123 }; 124 125 })(jQuery);
使用时,代码如下:
1 $(".pager-cont").pager({ 2 pagenumber: currentPage, 3 pagecount: parseInt($(".pager-cont").attr("data-pageCount")), 4 buttonClickCallback: function (pageclickednumber) { 5 var url = simpleUrl.replaceCurrentUrl({ page: pageclickednumber }); 6 window.location.href = url; 7 } 8 });
同样,要加上html标签确定显示位置
<div id="pager" class="pager-cont" data-pagecount="5"></div>
显示效果如下:
好啦,小伙伴们快去试试吧,两个控件之有 simple.url.js控件是共用的哦,其余的都要单独引用,当然小伙伴有精力了也可以再做修改,达到自己想要的效果。