發一個昨天晚上剛寫好的js分頁程序。
較早之前寫過一個,不過后來發現有問題,不好用,所以在端午節前夜,我把它重新寫了一遍。
下面開始正題:
目標:寫一個JS分頁函數,函數能夠根據給出的總頁數和當前頁自動生成相應的html代碼並且插入的到給定的父容器中。
實現:
分頁原理:分頁就是將很長的內容按規定長度分開,在PHP中是通過 mysql數據庫語言中 LIMIT來實現獲取指定部分的數據。
LIMIT的用法簡要在這簡要介紹下,詳細用法 請見 MySQL 5.5 Reference Manual。(我這里用的是5.5,當然也可以看看其他版本的)
LIMIT 有兩個參數(我不知道叫參數對不對)
LIMIT [offset,] rows
第一個為偏移量,第二個為返回的行數。
例如,我們要查詢時間最新的6條記錄可以這樣寫
SELECT * FROM `table` WHERE 1 ORDER BY `date` DESC LIMIT 0, 6
了解了這個,分頁就變得簡單了。。。
無論您使用AJAX 還是什么,改變的只是 數據庫的語句的LIMIT 中的 [offset]
頁碼算法
我們先對定義的變量進行下說明
1、函數參數 total_page, current_page, father 分別為總頁數,當前頁,父容器的id
2、pager_length pager 的長度 (具體見下圖)
3、head_length head 長度(具體見下圖)
4、tail_length tali的長度 (具體見下圖)(tail_length 需要和 head_length 相等 )
5、a_tag 插入的標簽名
6、a_class 插入標簽的類名
7、a_id 插入標簽的id
8、a_name 插入標簽的name
9、disable_class 不可用時的樣式的類( 比如當前頁為第一頁的時候,prev則為disable)
10、select_class 選中狀態的樣式的類(當前頁顯示的樣式,譬如換個背景啥的)
11、code 最后拼接生成的代碼
調用的其他函數為
1 function fill_tag(a_tag, a_class, a_id, a_name, a_html){ 2 a_class = (a_class == '') ? '' : ' class="'+a_class+'"'; 3 a_id = (a_id == '') ? '' : ' id="'+a_id+'"'; 4 a_name = (a_name == '') ? '' : ' name="'+a_name+'"'; 5 var code = '<'+a_tag+a_class+a_id+a_name+' >'+a_html+'</'+a_tag+'>'; 6 return code; 7 }
該函數返回一個給定了標簽名,class,id,name,以及標簽內容的的html字符串
下面開始具體的實現
分為兩種情況:
- 總頁數小於pager_length (如下圖)
- 總頁數大於pager_length(如下圖)
首先給出
情形1時的方法,這種情況很簡單,循環total_page次就可以了
1 if( total_page < pager_length ) 2 { 3 for(i = 0; i < total_page; i++) 4 { 5 code += (i+1 != current_page) ? fill_tag(a_tag, a_class, a_id, a_name, i+1) : fill_tag(a_tag, select_class, a_id, a_name, i+1); 6 } 7 }
而對於第二種情況,又可以分為三種子情況
分別如下
- 不需要出現左邊的"...";
- 不需要出現右邊的"...“;
- 兩邊都要出現"...";
下面我們對每一種情況具體的分析:
首先我們需要算出整個pager的半長,我叫他offset
1 var offset = ( pager_length - 1) / 2;
這個變量的作用 我們后面再談。
為了方便說明,我們此處假設
1 pager_length = 11; 2 header_length = tailer_length = 2;
此時offset = 5
1、不需要出現左邊的"...";
先看一個圖
此圖中,帶X的方框表示當前頁,可以看出:
當前頁小於等於offset+1的時候,不需要出現左邊的...
1 if( current_page <= offset + 1) 2 { 3 var tailer = ''; 4 //前header_length + main_length 個直接輸出之后加一個...然后輸出倒數的 tailer_length 個 5 for( i = 0; i < header_length + main_length; i ++) 6 code += (i+1 != current_page) ? fill_tag(a_tag, a_class, a_id, a_name, i+1) : fill_tag(a_tag, select_class, a_id, a_name, i+1); 7 code += fill_tag(a_tag, a_class, a_id, a_name, '...'); 8 for(i = total_page; i > total_page - tailer_length; i --) 9 tailer = fill_tag(a_tag, a_class, a_id, a_name, i) + tailer; 10 code += tailer; 11 }
此處由於對稱,需要繼續算出上圖中X后面的對應個數,同時還應該加上最后的tail(不知道tail 看看變量說明中的圖)
2、不需要出現右邊的"...“;
這個情況和上面的情況一致,我直接給出代碼
1 else if( current_page >= total_page - offset ) 2 { 3 var header = ''; 4 for( i = total_page; i >= total_page-main_length - 1; i --) 5 code = (( current_page != i ) ? fill_tag(a_tag, a_class, a_id, a_name, i) : fill_tag(a_tag, select_class, a_id, a_name, i)) + code; 6 code = fill_tag(a_tag, a_class, a_id, a_name, '...') + code; 7 for( i = 0; i < header_length ; i++) 8 header += fill_tag(a_tag, a_class, a_id, a_name, i + 1); 9 code = header + code; 10 }
3、兩邊都要出現"...";
除了上面兩種情況之外,剩下的就着一種情況了。
這種情況的head he tail 都是固定的,可以直接給出
1 var header = ''; 2 var tailer = ''; 3 //首先處理頭部 4 for( i = 0; i < header_length; i ++) 5 header += fill_tag(a_tag, a_class, a_id, a_name, i + 1); 6 header += fill_tag(a_tag, a_class, a_id, a_name, '...'); 7 //處理尾巴 8 for(i = total_page; i > total_page - tailer_length; i --) 9 tailer = fill_tag(a_tag, a_class, a_id, a_name, i) + tailer; 10 tailer = fill_tag(a_tag, a_class, a_id, a_name, '...') + tailer;
中間的情況:
由於是對稱的 我們前半部分叫做partA , 后半部分叫做partB
兩部分在同一個循環中處理
此時循環測次數應該為main的半長 + 當前頁;
因此有以下代碼
1 var offset_m = ( main_length - 1 ) / 2; 2 var counter = ( parseInt( current_page ) + parseInt( offset_m ) );
和
1 for(i = j = current_page ; i <= counter; i ++, j --) 2 { 3 partA = (( i == j ) ? '' : fill_tag(a_tag, a_class, a_id, a_name, j)) + partA; 4 partB += ( i == j ) ? fill_tag(a_tag, select_class, a_id, a_name, i) : fill_tag(a_tag, a_class, a_id, a_name, i); 5 }
最后一步,將head tail main 拼接起來
code = header + partA + partB + tailer;
這樣三中情況都處理完了,可是prev和next在哪里??? 請接着看
1 var prev = ( current_page == 1 ) ? fill_tag(a_tag, disable_class, a_id, a_name, 'prev') : fill_tag(a_tag, a_class, a_name, a_name, 'prev'); 2 var next = ( current_page == total_page ) ? fill_tag(a_tag, disable_class, a_id, a_name, 'next') : fill_tag(a_tag, a_class, a_name, a_name, 'next'); 3 code = prev + code + next; 4 document.getElementById(father).innerHTML=(code);
最后將他們放入父容器就OK啦。。。。
下面附上一個測試代碼,您可以直接把他復制到記事本中另存為html查看
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>無標題文檔</title> 6 </head> 7 <style type="text/css"> 8 .disable { 9 color:#FF0000; 10 font-weight:bold; 11 } 12 .select { 13 color:#00F; 14 font-weight:bold; 15 } 16 </style> 17 <script type="text/javascript"> 18 function update_page(total_page,current_page,father) 19 { 20 var total_page = parseInt( total_page ); 21 var current_page = parseInt( current_page ); 22 var pager_length = 11; //不包next 和 prev 必須為奇數 23 var pager = new Array( pager_length ); 24 var header_length = 2; 25 var tailer_length = 2; 26 //header_length + tailer_length 必須為偶數 27 var main_length = pager_length - header_length - tailer_length; //必須為奇數 28 29 var a_tag = 'li'; 30 var a_class = ''; 31 var a_id = ''; 32 var a_name = ''; 33 34 var disable_class = 'disable'; 35 var select_class = 'select'; 36 37 var i; 38 var code = ''; 39 if( total_page < current_page ) 40 { 41 alert('總頁數不能小於當前頁數'); 42 return false; 43 } 44 //判斷總頁數是不是小於 分頁的長度,若小於則直接顯示 45 if( total_page < pager_length ) 46 { 47 for(i = 0; i < total_page; i++) 48 { 49 50 code += (i+1 != current_page) ? fill_tag(a_tag, a_class, a_id, a_name, i+1) : fill_tag(a_tag, select_class, a_id, a_name, i+1); 51 } 52 } 53 //如果總頁數大於分頁長度,則為一下函數 54 else 55 { 56 //先計算中心偏移量 57 var offset = ( pager_length - 1) / 2; 58 //分三種情況,第一種左邊沒有... 59 if( current_page <= offset + 1) 60 { 61 var tailer = ''; 62 //前header_length + main_length 個直接輸出之后加一個...然后輸出倒數的 tailer_length 個 63 for( i = 0; i < header_length + main_length; i ++) 64 code += (i+1 != current_page) ? fill_tag(a_tag, a_class, a_id, a_name, i+1) : fill_tag(a_tag, select_class, a_id, a_name, i+1); 65 code += fill_tag(a_tag, a_class, a_id, a_name, '...'); 66 for(i = total_page; i > total_page - tailer_length; i --) 67 tailer = fill_tag(a_tag, a_class, a_id, a_name, i) + tailer; 68 69 code += tailer; 70 } 71 //第二種情況是右邊沒有... 72 else if( current_page >= total_page - offset ) 73 { 74 var header = ''; 75 //后tailer_length + main_length 個直接輸出之前加一個...然后拼接 最前面的 header_length 個 76 for( i = total_page; i >= total_page-main_length - 1; i --) 77 code = (( current_page != i ) ? fill_tag(a_tag, a_class, a_id, a_name, i) : fill_tag(a_tag, select_class, a_id, a_name, i)) + code; 78 code = fill_tag(a_tag, a_class, a_id, a_name, '...') + code; 79 for( i = 0; i < header_length ; i++) 80 header += fill_tag(a_tag, a_class, a_id, a_name, i + 1); 81 82 code = header + code; 83 } 84 //最后一種情況,兩邊都有... 85 else 86 { 87 var header = ''; 88 var tailer = ''; 89 //首先處理頭部 90 for( i = 0; i < header_length; i ++) 91 header += fill_tag(a_tag, a_class, a_id, a_name, i + 1); 92 header += fill_tag(a_tag, a_class, a_id, a_name, '...'); 93 //處理尾巴 94 for(i = total_page; i > total_page - tailer_length; i --) 95 tailer = fill_tag(a_tag, a_class, a_id, a_name, i) + tailer; 96 tailer = fill_tag(a_tag, a_class, a_id, a_name, '...') + tailer; 97 //處理中間 98 //計算main的中心點 99 var offset_m = ( main_length - 1 ) / 2; 100 var partA = ''; 101 var partB = ''; 102 var j; 103 var counter = (parseInt(current_page) + parseInt(offset_m)); 104 for(i = j = current_page ; i <= counter; i ++, j --) 105 { 106 partA = (( i == j ) ? '' : fill_tag(a_tag, a_class, a_id, a_name, j)) + partA; 107 partB += ( i == j ) ? fill_tag(a_tag, select_class, a_id, a_name, i) : fill_tag(a_tag, a_class, a_id, a_name, i); 108 } 109 //拼接 110 code = header + partA + partB + tailer; 111 112 113 } 114 } 115 116 117 var prev = ( current_page == 1 ) ? fill_tag(a_tag, disable_class, a_id, a_name, 'prev') : fill_tag(a_tag, a_class, a_name, a_name, 'prev'); 118 var next = ( current_page == total_page ) ? fill_tag(a_tag, disable_class, a_id, a_name, 'next') : fill_tag(a_tag, a_class, a_name, a_name, 'next'); 119 code = prev + code + next; 120 document.getElementById(father).innerHTML=(code); 121 } 122 function fill_tag(a_tag, a_class, a_id, a_name, a_html){ 123 a_class = (a_class == '') ? '' : ' class="'+a_class+'"'; 124 a_id = (a_id == '') ? '' : ' id="'+a_id+'"'; 125 a_name = (a_name == '') ? '' : ' name="'+a_name+'"'; 126 var code = '<'+a_tag+a_class+a_id+a_name+' >'+a_html+'</'+a_tag+'>'; 127 return code; 128 } 129 </script> 130 總頁數:<input type="text" value="" id="total_page" /><br /> 131 當前頁:<input type="text" value="" id="current_page" /><br /> 132 <input type="button" value="test" id="test" /> 133 <div><ul id="code"></ul></div> 134 <script type="text/javascript"> 135 document.getElementById('test').onclick = function(){ 136 var total_page = document.getElementById('total_page').value; 137 var current_page = document.getElementById('current_page').value; 138 update_page(total_page, current_page, 'code'); 139 // var tem = (fill_tag('a','class','id','name','xxxx')); 140 // alert(tem); 141 } 142 </script> 143 <body> 144 </body> 145 </html>
原創文章,轉載請注明出處 http://www.cnblogs.com/doug/archive/2012/06/23/2559568.html