背景:
調(diào)用PHP后端給的接口,以實(shí)現(xiàn)分頁的功能。由于我是沒造輪子的能力,所以翻了不少技術(shù)博客,經(jīng)過整合才算完成整個分頁功能。從一番查閱中,不難看出大概分為兩種不同的分頁:
一種是純前端的,就是在一次性加載完所有數(shù)據(jù)以后,通過隱藏多出來的部分,之后根據(jù)按鈕獲取列表長度中的每一小段,來實(shí)現(xiàn)分頁的效果;另一種是直接調(diào)用接口獲取到每一小段數(shù)據(jù)后分頁。第二種方法中,相當(dāng)于后臺已經(jīng)為我們做了分頁,前端只需要為每一個按鈕設(shè)置不同的節(jié)點(diǎn)獲取數(shù)據(jù)就行。此外由于第一種方法是一次性加載完全部數(shù)據(jù),所以在數(shù)據(jù)量較大的情況下首次加載的時間也會變長。下面會把兩種方法都羅列一下。
相關(guān)鏈接:
純javascript實(shí)現(xiàn)分頁(兩種方法): http://www.lai18.com/content/438532.html?from=cancel
簡單封裝分頁功能:pageView.js http://web.jobbole.com/87590/
利用JS生成分頁式table: http://blog.sciencenet.cn/blog-448935-603809.html
JS實(shí)現(xiàn)的分頁效果: http://www.kanqianduan.com/archives/469
純js實(shí)現(xiàn)分頁: http://www.cnblogs.com/jiechn/p/4095029.html
分頁的處理分為兩個部分,一個是內(nèi)容的顯示部分區(qū)域。一個是分頁按鈕區(qū)域。最后顯示區(qū)域的部分按照 純js實(shí)現(xiàn)分頁 來改的,按鈕區(qū)域按照 JS實(shí)現(xiàn)的分頁效果 的分頁思路,用ajax對接后端數(shù)據(jù)實(shí)現(xiàn)。對于按鈕方面,其中主要就是關(guān)于if判斷的思路,分布式完成每一個if。再改變每一個if中的效果,按照實(shí)際的UI稿要求做分頁的按鈕就可以了。
在這個項目中,由于后端給的接口不同,兩種不同的加載方式都使用到了。
效果展示

現(xiàn)在先來說說按鈕區(qū)域
<div class="pager" id="pagination" name="pagination">
<!--<li><a href="#">上一頁</a></li>
<li><a href="#" class="active">1</a></li>
<li><a href="#">2</a></li>
<li><a href="#">3</a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li><a href="#">下一頁</a></li>-->
</div>
HTML的部分就是這個樣子,我們需要獲取 pagination,然后在里面輸出分頁頁簽。并且提前寫好active的樣式。
window.onload = function (){
……
page({
id:"pagination", //當(dāng)前id
nowNum:1,//當(dāng)前頁
allNum:10, //顯示總頁媽
callBack:function(pno){
//回調(diào)函數(shù),在這里寫相關(guān)顯示傳參數(shù),如對于列表頁的展示
……
});
function page(opt){
if (!opt.id) {return false;}
var obj = document.getElementById(opt.id);
var nowNum = opt.nowNum || 1;//默認(rèn)值1
var allNum = opt.allNum || 5;//默認(rèn)值5
var callBack = opt.callBack || function(){};
//顯示 首頁btn
if(nowNum>=4 && allNum>=6){
var oA = document.createElement("a");//創(chuàng)建a標(biāo)簽
oA.href = "#1";//設(shè)置#的值
oA.innerHTML = "首頁"http://輸出內(nèi)容
obj.appendChild(oA);//添加oA
}
//顯示 上一頁btn
if(nowNum>=2){
var oA = document.createElement("a");
oA.href = "#" + (nowNum -1);
oA.innerHTML = "上一頁"
obj.appendChild(oA);
}
//當(dāng)總頁數(shù)小于等于5的時候
if (allNum<=5) {
//總頁數(shù)值為多少,輸出多少按鈕
for (var i =1;i<=allNum;i++) {
//創(chuàng)建a標(biāo)簽
var oA = document.createElement("a");
oA.href = "#"+i;
//當(dāng)前頁碼效果
if (nowNum == i) {
oA.className = "active";//新增樣式
oA.innerHTML = i;
}
//其他頁碼效果
else{
oA.innerHTML = i;
}
obj.appendChild(oA);
}
}
//當(dāng)總頁數(shù)大于5的時候
else{
for (var i =1;i<=5;i++) {
var oA = document.createElement("a");
//當(dāng)當(dāng)前按鈕是1或者2時,會出現(xiàn)負(fù)數(shù),需要控制
if (nowNum == 1 || nowNum == 2) {
oA.href = "#" + i;
if (nowNum == i) {
oA.className = "active";
oA.innerHTML = i;
}
else{
oA.innerHTML = i;
}
}
//通過總頁-當(dāng)前頁的結(jié)果,判斷點(diǎn)擊最后的按鈕時,如何輸出
else if((allNum -nowNum) == 0 ||(allNum -nowNum) == 1){
oA.href = "#" + (allNum - 5 + i);
if ((allNum -nowNum) == 0 && i==5) {
oA.className = "active";
oA.innerHTML = (allNum - 5 + i);
}
else if((allNum -nowNum) == 1 && i==4){
oA.className = "active";
oA.innerHTML = (allNum - 5 + i);
}
else{
oA.innerHTML =(allNum - 5 + i);
}
}
else{
oA.href = "#" + (nowNum - 3 + i);
if (i==3) {//使當(dāng)前頁簽始終處于中間
oA.className = "active";
oA.innerHTML =(nowNum - 3 + i);
}
else{
oA.innerHTML = (nowNum - 3 + i);
}
}
obj.appendChild(oA);
}
}
//顯示 尾頁btn
if((allNum - nowNum)>=3 && allNum >=6){
var oA = document.createElement("a");
oA.href = "#" + allNum;
oA.innerHTML = "尾頁"
obj.appendChild(oA);
}
//顯示 下一頁btn
if((allNum - nowNum)>=1){
var oA = document.createElement("a");
oA.href = "#" + (nowNum +1);
oA.innerHTML = "下一頁"
obj.appendChild(oA);
}
//callBack函數(shù)執(zhí)行
callBack(nowNum,allNum);
//ithead 為表格需要輸出的內(nèi)容
var ithead = document.getElementById("idData");
//獲得表格的行數(shù)長度
var num = idData.childNodes.length;
//無數(shù)據(jù)如何輸出
if(num == 0){
obj.style.display="none";
var oB = document.getElementById("warning");
oB.innerHTML = "當(dāng)前無成員周報數(shù)據(jù)";
}
else{
//給a添加點(diǎn)擊事件
var aA = obj.getElementsByTagName("a");
for (var i =0;i<aA.length;i++) {
aA[i].onclick = function(){
var nowNum = parseInt(this.getAttribute("href").substring(1));
obj.innerHTML = "";
page({//重新賦值
id:opt.id,
nowNum:nowNum,
allNum:allNum,
callBack:callBack
});
return false;
};
}
}
}
創(chuàng)建按鈕的方式方法其實(shí)都是一樣的,需要注意的是賦值和判斷的問題。
而分頁展示區(qū)域的代碼則放在回調(diào)函數(shù)里。并且在此之前需要聲明變量。
這里在成功獲取了后臺ajax數(shù)據(jù)以后,先需要確定一共有多少行數(shù)據(jù),確定每頁有多少行,該例子中每頁5行,故使用 總行數(shù)/每頁行數(shù) = 總頁數(shù)。因為可能并非整除,故需要使用 Math.ceil 向上取整。
$.ajax({
type:"get",
url:"/api/admin/show_weekly.php?session="+session_id,
dataType:'json',
success:function(json){
var num = json["data"].length;//JSON字符串的條數(shù)
var pageSize = 5; //每頁顯示行數(shù)
var page_num = Math.ceil(num/pageSize); //總頁數(shù)
var page_now = page_num -(page_num-1); //等于第一頁
為對象設(shè)置好變量值,回調(diào)函數(shù)中直接調(diào)用接口輸出數(shù)據(jù)。
page({
id:"pagination", //當(dāng)前id
nowNum:page_now,//當(dāng)前頁
allNum:page_num, //顯示總頁媽
callBack:function(pno){
var itable = document.getElementById("idData");
$("#idData").html("");
for (var i =0; i <num;i++) {
itable.innerHTML += "<tr><td>"+ group(json["data"][i].group_id) + "</td>" +
"<td>"+ json["data"][i].name + "</td>" +
"<td>"+ json["data"][i].week_num + "</td>" +
"<td>"+ status(json["data"][i].status) + "</td>" +
"<td>"+ json["data"][i].text+ "</td></tr>";
};
之前提到有一次性加載數(shù)據(jù)和后臺處理以后調(diào)用接口分次加載兩種處理數(shù)據(jù)的方式。如果調(diào)用的是第二種,下面代碼可直接省略。以下為對于每頁多出行數(shù)數(shù)據(jù)的處理。
var totalPage = 0; // 總頁數(shù)
//總共分幾頁
if(num/pageSize>parseInt(num/pageSize)){
totalPage = parseInt(num/pageSize)+1;
}else{
totalPage = parseInt(num/pageSize);
}
var currentPage = pno;//當(dāng)前頁數(shù)
var startRow = (currentPage - 1) * pageSize +1;
var endRow = currentPage * pageSize;
endRow = (endRow >num)? num:endRow;
for (var i=1;i<(num+1);i++) {
var irow = itable.rows[i-1];
if (i>=startRow && i <=endRow) {
irow.style.display = "table-row";
} else{
//超出的部分隱藏掉
irow.style.display = "none";
}
}
}
});
},
error:function(json){
if (json.error != null) {
alert(json.error)
}
else{
alert("缺少必要的參數(shù)或參數(shù)為非數(shù)字");
}
}
});
后臺SQL控制的好,完全可以將數(shù)據(jù)的切割交由他們,比起一次性加載完所有數(shù)據(jù),由后臺來控制數(shù)據(jù)顯然更合理。