無刷新分頁技術
技術點:JQuery+JSON
步驟1:貼下面的JS插件
split_util.js
var jsCommonCp=1 ; //默認顯示第一頁
var jsCommonLs=10 ; //默認顯示10條數據
var jsCommonPageSize ; //總頁數,將其定義爲全局變量
var jsCommonCol="" ; //列名稱
var jsCommonKw="" ; //關鍵詞
function createSplitBar(data){ //創建分頁條
// console.log("allRecords:"+allRecords) ;
calcPageSize(data.allRecords) ; //分頁開始之後首先要計算總頁數
clearBar() ; //清空已有的分頁數據條,避免重複生成
//創建分頁工具條
// console.log("jsCommonCp:"+jsCommonCp) ;
previousPageBar() ;
addBar(1) ; //第一頁應該一直出現
var seed=3 ; //定義種子數
if(jsCommonCp>seed*2){ //超過預期的內容纔會出現
addDetailsPageBar() ; //增加省略頁面
var startPage=jsCommonCp-seed ; //開始頁
for(var x=startPage;x<=jsCommonCp+seed;x++){
if(x<jsCommonPageSize){
addBar(x) ;
}
}
if(jsCommonCp+seed*2<jsCommonPageSize){ //後面還有很多頁
addDetailsPageBar() ; //增加省略頁面
}
}else{ //現在的頁數還小於種子數
for(var x=2;x<jsCommonCp+seed;x++){
addBar(x) ;
}
if(jsCommonCp+seed<jsCommonPageSize){ //後面還有很多頁
addDetailsPageBar() ; //增加省略頁面
}
}
addBar(jsCommonPageSize) ; //尾頁應該一直出現
nextPageBar() ;
} ;
function addBar(index){ //定義一個函數專門負責追加每一個li元素實現分頁的控制顆粒
var liObj=$("<li></li>") ; //先創建元素在配置,因爲後面牽扯到事件問題
var aObj=$("<a style=\"cursor:pointer\">"+index+"</a>") ;
if(jsCommonCp == index){ //現在爲當前所在頁
aObj.addClass("active") ; //表示當前頁爲可用頁
}else{
aObj.on("click",function(){
jsCommonCp=index ; //改變當前頁爲可用頁
loadData() ; //重新加載新的數據
}) ;
}
liObj.append(aObj) ;
$("#pageControl").append(liObj) ; //追加到分頁控制條
} ;
//如果要想進行分頁,那麼必須知道到底有多少頁,那麼這個總頁數是通過計算得來的
function calcPageSize(allRecords){ //計算總頁數
if(allRecords==0){
jsCommonPageSize=1 ; //保持1頁
}else{
//此時計算總頁數時一定會存在小數點問題,將其用parseInt()函數解決掉
jsCommonPageSize=parseInt((allRecords+jsCommonLs-1)/jsCommonLs);
}
} ;
function clearBar(){
$("#splitBarDiv").empty() ; //清空分頁條所有的內容
$("#splitBarDiv").append("<ul id=\"pageControl\" class=\"pagination\"></ul>") ; //追加一個ul
} ;
function previousPageBar(){
var liObj=$("<li></li>") ; //先創建元素在配置,因爲後面牽扯到事件問題
var aObj=$("<a style=\"cursor:pointer\">上一頁</a>") ;
if(jsCommonCp == 1){ //現在爲第一頁
aObj.addClass("disabled") ; //如果爲第一頁,則上一頁不可用
}else{
aObj.on("click",function(){
if(jsCommonCp>1){
jsCommonCp-- ; //改變當前頁爲上一頁
loadData() ; //重新加載新的數據
}
}) ;
}
liObj.append(aObj) ;
$("#pageControl").append(liObj) ; //追加到分頁控制條
} ;
function nextPageBar(){
var liObj=$("<li></li>") ; //先創建元素在配置,因爲後面牽扯到事件問題
var aObj=$("<a style=\"cursor:pointer\">下一頁</a>") ;
if(jsCommonCp == jsCommonPageSize){ //現在爲尾頁
aObj.addClass("disabled") ; //如果爲尾頁,則下一頁不可用
}else{
aObj.on("click",function(){
if(jsCommonCp < jsCommonPageSize){
jsCommonCp++ ; //改變當前頁爲下一頁
loadData() ; //重新加載新的數據
}
}) ;
}
liObj.append(aObj) ;
$("#pageControl").append(liObj) ; //追加到分頁控制條
} ;
function addDetailsPageBar(){ //增加省略頁
$("#pageControl").append("<li><span>...</span></li>");
} ;
split_search.js
//<div id="searchDiv"></div>
function createSearchBar(data){ //生成檢索框
jsCommonCol = data.col ; //當前使用的模糊查詢列
jsCommonKw=data.kw ; //當前使用的默認關鍵字
clearSearchBar() ; //清空原有的搜索框
addSelectColumn(data.columnData) ; //創建下拉列表框
addSearchText(jsCommonKw,data.allRecords) ; //創建搜索框
} ;
function clearSearchBar(){
$("#searchDiv").empty() ;
} ;
function addSearchText(kw,allRecords){
$("#searchDiv").append("<input type=\"text\" name=\"kw\" id=\"kw\" value=\""+kw+"\">") ;
var butObj=$("<input type=\"button\" value=\"檢索\">") ; //檢索按鈕
butObj.on("click",function(){
jsCommonCol=$("#col").val() ; //重新讀取下拉列表的值
jsCommonKw=$("#kw").val() ; //重新讀取關鍵詞
loadData() ; //重新加載數據
}) ;
$("#searchDiv").append(butObj) ;
$("#searchDiv").append("<div>本次查詢一共返回了"+allRecords+"條記錄</div>") ;
} ;
function addSelectColumn(columnData){
var selectObj=$("<select id=\"col\"></select>");
var result=columnData.split("|") ; //拆分字符串
for(var x=0;x < result.length;x++){
var temp=result[x].split(":") ; //保存每一個字段
if(jsCommonCol==temp[1]){
selectObj.append("<option value=\""+temp[1]+"+\" selected>"+temp[0]+"</option>") ; //選中
}else{
selectObj.append("<option value=\""+temp[1]+"\" >"+temp[0]+"</option>") ;
}
}
$("#searchDiv").append(selectObj) ;
} ;
以上兩個插件不用改變,直接貼代碼就行
步驟二:編寫HTML/JSP頁面
dept_list.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>無刷新分頁技術</title>
<script type="text/javascript" src="jquery/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="jquery/bootstrap.min.js"></script>
<script type="text/javascript" src="js/split_util.js"></script>
<script type="text/javascript" src="js/split_search.js"></script>
<script type="text/javascript" src="js/dept_list.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="searchDiv"></div>
<div id="deptDiv">
<table border="1" id="deptTab">
<tr>
<td>部門編號</td>
<td>部門名稱</td>
</tr>
</table>
</div>
<div id="splitBarDiv"></div>
</body>
</html>
dept_list.js
$(function(){ //只要是無刷新分頁,就要進行Ajax動態設置
loadData() ; //只要調用這個函數就可以實現表格數據填充以及分頁的自動生成
}) ;
function loadData(){ //負責數據的加載
//此處既然是無刷新分頁,那麼就要進行異步數據加載
$.post("PageServlet",{
"cp" : jsCommonCp ,
"ls" : jsCommonLs ,
"col" : jsCommonCol ,
"kw" : jsCommonKw
} ,function(json){
createSplitBar(json); //有總記錄數才能驅動分頁組件
createSearchBar(json) ; //生成檢索框
//隨後生成分頁的數據,會有所不同
clearTable() ; //清空表格行
for(var x=0;x<json.allDepts.length;x++){
var deptno=json.allDepts[x].deptno ;
var dname=json.allDepts[x].dname ;
addTableRow(deptno,dname) ; //增加行
}
},"json");
} ;
function addTableRow(deptno,dname){
$("#deptTab").append("<tr><td>"+deptno+"</td><td>"+dname+"</td></tr>");
} ;
function clearTable(){ //清空表格行
$("#deptTab tr:gt(0)").remove(); ;
} ;
總結:
以上的兩個文件必須做改寫:Ajax的URL、表格的格式、生成row的函數;
其實無刷新分頁節省了和後臺的交互
步驟三:控制層代碼
PageServlet.java
package cn.zzu.wcj.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@WebServlet(urlPatterns="/PageServlet")
public class PageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//分頁操作的幾個核心參數:cp,ls,col,kw
request.setCharacterEncoding("UTF-8") ;
response.setCharacterEncoding("UTF-8") ;
response.setContentType("text/html");
int currentPage=1 ;
int lineSize=5 ;
String column=null ;
String keyWord=null ;
try{
currentPage=Integer.parseInt(request.getParameter("cp")) ;
}catch(Exception e){}
try{
lineSize=Integer.parseInt(request.getParameter("ls")) ;
}catch(Exception e){}
column=request.getParameter("col") ;
keyWord=request.getParameter("kw") ;
if(column==null || "".equals(column)){
column="dname" ;
}
if(keyWord==null){
keyWord="" ;
}
String columnData="部門編號:deptno|部門名稱:dname|部門位置:loc" ;
System.out.println("[分頁參數]cp="+currentPage+",ls="+lineSize+",col="+column+",kw="+keyWord);
JSONObject all=new JSONObject() ;
all.put("allRecords", 4800) ;
all.put("columnData", columnData) ; //作爲下拉列表內容存在
all.put("col", column) ; //回傳列
all.put("kw", keyWord) ; //回傳關鍵詞
JSONArray array=new JSONArray() ;
//模擬JDBC
for(int x=currentPage*lineSize;x<currentPage*lineSize+10;x++){
JSONObject obj=new JSONObject() ;
obj.put("deptno", x) ;
obj.put("dname", "ZZU-"+x) ;
array.add(obj) ;
}
all.put("allDepts", array) ;
response.getWriter().print(all);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
}
總結:
這裏最需要注意幾個參數的回傳:allRecords、columnData、col、kw(columnData和數據庫字段和中文名要一一對應,如”部門編號:deptno|部門名稱:dname|部門位置:loc”)、allDepts(換成你想要傳回的數據) , 接收:cp、ls、col、kw;
結合SpringMVC或Struts2把以上的控制層改寫進去,就可以完成無刷新分頁,我之前的寫的分頁插件沒這個好用,大家可以結合Bootstrap讓這個分頁插件更炫酷