DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> jQuery入門知識 >> JQuery特效代碼 >> 一款Jquery 分頁插件的改造方法(服務器端分頁)
一款Jquery 分頁插件的改造方法(服務器端分頁)
編輯:JQuery特效代碼     
分頁幾乎是每個外部程序必不可少的東西,在webform時代很多人都用過AspNetPager這個用戶控件吧,用的人之多其實就在於它的優點:傳給它幾個參數就可以生成像樣的分頁,其實這個也是絕大多數程序員(包括我)的致命缺點:樣式..,我對於咱們來說用嘗試用CSS把一個模塊調美觀好看所花的時間遠遠超過了實現功能所需的時間- -!
現在越來越多做web的開始采用.NET MVC框架,拋開一切服務器控件,回歸正宗的B/S編程,享受靈活控制好處之余,也得花費很多功夫,很多地方都得自己去實現,例如分頁這樣的東西。簡單實現功能肯定很簡單,但是要做到好用,通用,性能好,易於修改也不是一個很簡單的事情,所以各種JS分頁控件大顯身手,如jquery pager、jquery Pagination等等,調用很方便,生成效果也很好,唯一缺點就是都是內存分頁,數據量少點還好,如果成千上萬幾百上千萬數據可就要命了。要是能有一個調用方便還能配合進行服務端分頁的前端控件該多好呢:)
說了這麼多接下來就給大家看看我利用一個富客戶端UI框架(DWZ)中分離改造出來的一個JS分頁控件,先看看效果圖:

頁面代碼:

代碼如下:
<div class="panelBar">
<div class="pages">
<span>顯示</span>
@Html.DropDownList("numPerPage", ViewBag.dNumPerPage as SelectList, new { onchange = "PageBreak({numPerPage:this.value})" })
<span>條,共 @Model.TotalCount 條</span>
</div>
<div class="pagination" totalcount="@Model.TotalCount" numperpage="@Model.NumPerPage"
pagenumshown="@Model.PageNumShown" currentpage="@Model.CurrentPage">
</div>

其實這個完全可以寫成HtmlHelper調用,例如 Html.Pagination(ViewBag.dNumPerPage,Model.TotalCount,Model.NumPerPage,Model.PageNumShown,Model.CurrentPage)
這樣,一條語句就可以。
原理就是用js通過獲取 class="pagination" 的div的自定義屬性:總頁數TotalCount,每頁多少條NumPerPage ,顯示多少頁碼 PageNumShown,當前頁數CurrentPage,
然後將這四個屬性傳給分頁js,分頁js內利用這幾個關鍵屬性進行計算,然後將預制好的分頁模板進行替換,展現出分頁效果。
為了好讓美工根據項目整體風格來對分頁進行調整,實現好的分工合作的原則,這裡分頁的js和CSS和分頁替換模板是完全分開的,不至於程序看CSS暈,美工看JS暈。
分頁js分為兩部分,一部分只負責根據參數計算分頁(pagination.js),一部分是作之前的准備工作的(core.js),一些參數的預制,在這裡其實只有一個就是分頁模板的位置參數,還有一些分頁內部用到的自定義擴展函數,分頁模板為了美工便於修改觀察,不混在js裡面,而又便於js利用,這裡用XML的格式(pagination.xml),先把代碼貼出來
 core.js:
代碼如下:
(function($){
$.extend(String.prototype, {
isPositiveInteger:function(){
return (new RegExp(/^[1-9]\d*$/).test(this));
},
replaceAll:function(os, ns) {
return this.replace(new RegExp(os,"gm"),ns);
}
});
$.fn.extend({
hoverClass: function(className){
var _className = className || "hover";
return this.each(function(){
$(this).hover(function(){
$(this).addClass(_className);
},function(){
$(this).removeClass(_className);
});
});
}
});
})(jQuery);
var DWZ = {
frag: {},
init: function (pageFrag) {
$.ajax({
type: 'GET',
url: pageFrag,
dataType: 'xml',
timeout: 50000,
cache: false,
error: function (xhr) {
alert('Error loading XML document: ' + pageFrag + "\nHttp status: " + xhr.status + " " + xhr.statusText);
},
success: function (xml) {
DWZ.frag["pagination"]= $(xml).find("#pagination").text();
}
});
}
};

pagination.js:
代碼如下:
(function($){
$.fn.pagination = function(opts){
var setting = {
first$:"li.j-first", prev$:"li.j-prev", next$:"li.j-next", last$:"li.j-last", nums$:"li.j-num>a", jumpto$:"li.jumpto",
pageNumFrag:'<li class="#liClass#"><a href="#">#pageNum#</a></li>'
};
return this.each(function(){
var $this = $(this);
var pc = new Pagination(opts);
var interval = pc.getInterval();
var pageNumFrag = '';
for (var i=interval.start; i<interval.end;i++){
pageNumFrag += setting.pageNumFrag.replaceAll("#pageNum#", i).replaceAll("#liClass#", i==pc.getCurrentPage() ? 'selected j-num' : 'j-num');
}
$this.html(DWZ.frag["pagination"].replaceAll("#pageNumFrag#", pageNumFrag).replaceAll("#currentPage#", pc.getCurrentPage())).find("li").hoverClass();
var $first = $this.find(setting.first$);
var $prev = $this.find(setting.prev$);
var $next = $this.find(setting.next$);
var $last = $this.find(setting.last$);
if (pc.hasPrev()){
$first.add($prev).find(">span").hide();
_bindEvent($prev, pc.getCurrentPage()-1, pc.targetType());
_bindEvent($first, 1, pc.targetType());
} else {
$first.add($prev).addClass("disabled").find(">a").hide();
}
if (pc.hasNext()) {
$next.add($last).find(">span").hide();
_bindEvent($next, pc.getCurrentPage()+1, pc.targetType());
_bindEvent($last, pc.numPages(), pc.targetType());
} else {
$next.add($last).addClass("disabled").find(">a").hide();
}
$this.find(setting.nums$).each(function(i){
_bindEvent($(this), i+interval.start, pc.targetType());
});
$this.find(setting.jumpto$).each(function(){
var $this = $(this);
var $inputBox = $this.find(":text");
var $button = $this.find(":button");
$button.click(function(event){
var pageNum = $inputBox.val();
if (pageNum && pageNum.isPositiveInteger()) {
PageBreak({ pageNum: pageNum });
}
});
$inputBox.keyup(function(event){
if (event.keyCode == 13) $button.click();
});
});
});
function _bindEvent(jTarget, pageNum, targetType){
jTarget.bind("click", {pageNum:pageNum}, function(event){
PageBreak({ pageNum: event.data.pageNum });
event.preventDefault();
});
}
}
var Pagination = function(opts) {
this.opts = $.extend({
targetType:"navTab", // navTab, dialog
totalCount:0,
numPerPage:10,
pageNumShown:10,
currentPage:1,
callback:function(){return false;}
}, opts);
}
$.extend(Pagination.prototype, {
targetType:function(){return this.opts.targetType},
numPages:function() {
return Math.ceil(this.opts.totalCount/this.opts.numPerPage);
},
getInterval:function(){
var ne_half = Math.ceil(this.opts.pageNumShown/2);
var np = this.numPages();
var upper_limit = np - this.opts.pageNumShown;
var start = this.getCurrentPage() > ne_half ? Math.max( Math.min(this.getCurrentPage() - ne_half, upper_limit), 0 ) : 0;
var end = this.getCurrentPage() > ne_half ? Math.min(this.getCurrentPage()+ne_half, np) : Math.min(this.opts.pageNumShown, np);
return {start:start+1, end:end+1};
},
getCurrentPage:function(){
var currentPage = parseInt(this.opts.currentPage);
if (isNaN(currentPage)) return 1;
return currentPage;
},
hasPrev:function(){
return this.getCurrentPage() > 1;
},
hasNext:function(){
return this.getCurrentPage() < this.numPages();
}
});
})(jQuery);

分頁模板pagination.xml:
代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<_AJAX_>
<!-- pagination -->
<_PAGE_ id="pagination"><![CDATA[
<ul>
<li class="j-first">
<a class="first" href="#"><span>首頁</span></a>
<span class="first"><span>首頁</span></span>
</li>
<li class="j-prev">
<a class="previous" href="#"><span>上一頁</span></a>
<span class="previous"><span>上一頁</span></span>
</li>
#pageNumFrag#
<li class="j-next">
<a class="next" href="#"><span>下一頁</span></a>
<span class="next"><span>下一頁</span></span>
</li>
<li class="j-last">
<a class="last" href="#"><span>末頁</span></a>
<span class="last"><span>末頁</span></span>
</li>
<li class="jumpto"><input class="jumptotext" type="text" value="#currentPage#" /><input class="goto" type="button" value="確定" /></li>
</ul>
]]></_PAGE_>
</_AJAX_>

pagination.css:
代碼如下:
@charset "utf-8";
/* CSS Document */
/* public */
ul li,ol li,dt,dd {list-style:none;}
a:link{
color:#000000;
text-decoration:none;
}
a:visited{
color:#000000;
text-decoration:none;
}
a:hover{
color:#000000;
text-decoration:underline;
}
/* pagination */
.panelBar{
margin-top:12px;
height:26px;
line-height:26px;
}
.panelBar ul{
float:left;
}
.panelBar ul li{
float:left;
}
.disabled{
padding:0 6px;
}
.j-num{
padding:0 4px;
}
.pages
{
margin-top:12px;
float:left;
}
.pagination
{
float:left;
padding-left:50px;
}
.pagination li, .pagination li.hover { padding:0 0 0 5px;}
.pagination a, .pagination li.hover a, .pagination li span { float:left; display:block; padding:0 5px 0 0; text-decoration:none; line-height:23px; background-position:100% -150px;}
.pagination li.selected a{color:red; font-weight:bold;}
.pagination span, .pagination li.hover span { float:left; display:block; height:23px; line-height:23px; cursor:pointer;}
.pagination li .first span, .panelBar li .previous span { padding:0 0 0 10px;}
.pagination li .next span, .panelBar li .last span { padding:0 10px 0 0;}
.pagination li .first span { background:url(images/pagination/pagination_first_a.gif) left 5px no-repeat;}
.pagination li .previous span { background:url(images/pagination/pagination_previous_a.gif) left 5px no-repeat;}
.pagination li .next span { background:url(images/pagination/pagination_next_a.gif) right 5px no-repeat;}
.pagination li .last span { background:url(images/pagination/pagination_last_a.gif) right 5px no-repeat;}
.pagination li .last { margin-right:5px;}
.pagination li.disabled { background:none;}
.pagination li.disabled span, .grid .pagination li.disabled a { background-position:0 100px; cursor:default;}
.pagination li.disabled span span { color:#666;}
.pagination li.disabled .first span { background:url(images/pagination/pagination_first_span.gif) left 5px no-repeat;}
.pagination li.disabled .previous span { background:url(images/pagination/pagination_previous_span.gif) left 5px no-repeat;}
.pagination li.disabled .next span { background:url(images/pagination/pagination_next_span.gif) right 5px no-repeat;}
.pagination li.disabled .last span { background:url(images/pagination/pagination_last_span.gif) right 5px no-repeat;}
.pagination li.disabled .last { margin-right:5px;}
.pagination li.jumpto { padding:2px 2px 0 7px; background-position:0 -200px;}
.pagination li.jumpto .jumptotext { float:left; width:30px; height:15px; padding:1px; border-color:#acaeaf; background:#ffffff; border:1px solid #9999cc;}
.pagination li.jumpto .goto { float:left; display:block; overflow:hidden; width:16px; height:19px; border:0; text-indent:-1000px; background:url(images/pagination/pagination_goto.gif) no-repeat; cursor:pointer;}

我看CSS也頭疼,這個是我找一個朋友寫的,自己又改了改
接下來講講使用方法:
首先 指定自己分頁模板的路徑 DWZ.init("js/pagination.xml"); 然後調用分頁:
代碼如下:
$(function(){
$("div.pagination").each(function () {
var $this = $(this);
$this.pagination({
totalCount: $this.attr("totalCount"),
numPerPage: $this.attr("numPerPage"),
pageNumShown: $this.attr("pageNumShown"),
currentPage: $this.attr("currentPage")
});
});
});

這裡為什麼用each呢,為啥不直接$("div.pagination").pagination({})呢,大家應該想到了,有挺多時候用戶喜歡在列表的上下都放分頁便於操作,這兩塊js其實可以單獨放一個文件,需要用到分頁的文件引用即可,因為程序真正用到的是web和服務器端交換所關心的數據,totalCount numPerPage pageNumShown currentPage ,之前所做的所有都只是實現好用通用的框架。現在無需改動的東西都做好了,怎麼實現交互呢,很簡單:點擊頁碼或者選擇每頁顯示下拉框或者點擊go按鈕時候都會觸發一個自定義函數 PageBreak ,這個函數內部就大家想實現什麼具體去寫,例如
代碼如下:
function PageBreak(args) {
alert(args["pageNum"]||args["numPerPage"]);
}

在這裡面可以用js取得當前的totalCount numPerPage pageNumShown curren,和頁面上篩選的form的值一並ajax提交給後端頁面,然後接收返回的數據,加載到指定位置,並且注意給<div class="pagination" >這個DIV的自定義屬性重新賦值然後調用一下pagination方法即可,不知道寫清楚沒有,先去吃飯了,如果有問題可以留言,如果不清楚具體使用的人多,打算後續寫兩種用法,一種是返回數據直接返回這個div的,一個是只返回表單中行數據和div的4個自定義屬性,然後js動態賦值的
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved