最近做的一個 PC
端的需求,這個需求中有一個小點,頁面底部有一塊列表區域,這個列表的資料量比較大,需要進行分頁控制,切換頁碼的時候,傳送一個 ajax
請求,在頁面無重新整理的情況下,實現列表資料的重新整理,所以就涉及到了前端分頁功能,到網上看了一圈,發現那些開源的相關外掛要麼有各種依賴,要麼太複雜用不上,要麼上手有點困難,所以就想著應該也不太難,自己寫個得了。
關於這種分頁功能,平時很常見,不過需要自己動手做的需求卻很少,所以一直停留在知道應該就是那麼回事,但實際上自己從來沒怎麼探究過的層面上,知道應該會涉及到一些邏輯判斷,不會實現起來應該沒什麼難度,然而,真的等到自己著手實現的時候,才知道什麼叫想得美。
簡單介紹
先上效果圖:
有點類似於 Github
搜尋結果頁的底部分頁,可能部分邏輯有點出入,但總體應該差不多
程式碼使用 ES6
語法,這個外掛其實是一個 class
,babel
打包後可相容到 IE9
,原生js無任何依賴。
整個外掛類程式碼 SimplePagination
加上空行註釋什麼的共約 200
行左右,不過其中有部分程式碼是輔助程式碼,例如初始化、選擇器、增刪類等方法,再除去空行註釋,最後剩下的核心程式碼也就不到 100
行的樣子。
主要的判斷邏輯都在 gotoPage
這個方法中,因為需要考慮到各種情況,所以裡面寫了很多的 if.. else...
判斷,沒寫下這些程式碼之前,我覺得這個東西充其量也就幾個判斷差不多了,但是沒想到會有這麼多,每次的頁碼切換都對應著不同的判斷分支,比較繁瑣。
核心程式碼簡要分析
核心方法是 gotoPage
,乍一看,此方法中到處都是 if...else..
判斷,似乎無從下手,但是不論頁碼如何變,也不管是如何切換到某個頁碼的,只需要記住一點,那就是切換到某個頁碼時,這個頁碼對應的整個分頁元件的狀態是確定的,這一點很重要,只要把握住了這點,那一連串的 if...else...
判斷的意義其實也就清晰了。
此方法最外層的一個 if...else...
判斷是針對頁碼是否需要顯示省略號佔位符的,如果頁碼總數小於頁面上課同時存在的頁碼數,那麼就不需要省略符號佔位了,就是一種比較簡單的分頁,例如下面這種:
對於這種情況,只需要在切換頁碼的時候,變換 active
的頁碼即可。
至於另外那種需要省略號佔位的情況,才是複雜的地方,而這個分支裡,最外層有 3
個判斷,這 3
個判斷包括了所有頁碼切換的情況。
第一個判斷是針對分頁元件左邊不需要出現省略號佔位符的情況,例如下面這種:
第二個判斷是針對分頁元件右邊不需要出現省略號佔位符的情況,例如下面這種:
第三個判斷是針對分頁元件兩邊都需要出現省略號佔位符的情況,例如下面這種:
整個分頁元件的所有狀態,肯定都被包括在這三種狀態中,所以接下來的邏輯判斷只需要針對這三個狀態就行了。
用法
首先 new
這個類,然後呼叫 init
方法,傳入相應的引數即可,例如:
const slp = new SimplePagination(12)
slp.init({
container: `.box`,
maxShowBtnCount: 3,
onPageChange: state => {console.log(`pagination change:`, state.pageNumber)}
})
複製程式碼
其中,在 new
例項化 SimplePagination
類的時候,需要傳入 1
個引數,即總頁數(totalPageCount
),分頁外掛需要根據此值來進行頁碼元素的繪製。
呼叫 init
方法時,為了方便傳參,此方法接收一個物件,物件中存在以下屬性:
引數名 | 型別 | default |
說明 | 是否必填 |
---|---|---|---|---|
container |
string |
body |
一個DOM 元素的選擇器,id 或者 class 均可,表示分頁的容器 |
否 |
maxShowBtnCount |
number |
5 |
不包括開頭和結尾的兩個固定按鈕外,中間最多展示幾個數字頁碼按鈕 | 否 |
pCName |
string |
page-li |
所有的分頁頁碼元素的統一類名,包括上一頁、下一頁 | 否 |
activeCName |
string |
page-active |
當選中頁碼時新增的類名class |
否 |
dataNumberAttr |
string |
頁碼元素上的一個屬性,其值為頁碼元素所表示的頁碼 | data-number |
否 |
prevCName |
string |
page-prev |
上一頁 按鈕的類名class |
否 |
nextCName |
string |
page-next |
下一頁 按鈕的類名class |
否 |
disbalePrevCName |
string |
no-prev |
禁用 上一頁 按鈕的可用性時給此按鈕新增的類名class |
否 |
disbaleNextCName |
string |
no-next |
禁用 下一頁 按鈕的可用性時給此按鈕新增的類名class |
否 |
pageNumberCName |
string |
page-number |
不包括 上一頁 下一頁、省略號佔位符按鈕之外的所有頁碼元素統一類名 | 否 |
swEvent |
string |
click |
觸發切換頁面的事件 | 否 |
onPageChange |
string |
– | 頁碼切換時的回撥函式 | 否 |
除了根據頁面上的頁碼和上一頁、下一頁按鈕進行頁碼切換外,外掛還有一個 gotoPage
方法可用,此方法接收一個型別為 number
的引數,呼叫此方法,就會跳到此引數指定的頁碼上,例如,跳轉到頁碼 9
上:
slp.gotoPage(9)
複製程式碼
如果傳入的引數不是合法的頁碼,則不會進行任何操作。
本文的可執行示例程式碼已經放到 Github上了,有興趣的可以看下~
SimplePagination
這個類主要在於頁碼切換的邏輯判斷,外加簡單地組裝了DOM
結構,我在示例程式碼中隨便寫了個樣式,如果你不喜歡這個樣式完全可以自己重寫。