原生 JS實現一個簡單分頁外掛

清夜發表於2019-03-04

最近做的一個 PC端的需求,這個需求中有一個小點,頁面底部有一塊列表區域,這個列表的資料量比較大,需要進行分頁控制,切換頁碼的時候,傳送一個 ajax請求,在頁面無重新整理的情況下,實現列表資料的重新整理,所以就涉及到了前端分頁功能,到網上看了一圈,發現那些開源的相關外掛要麼有各種依賴,要麼太複雜用不上,要麼上手有點困難,所以就想著應該也不太難,自己寫個得了。

關於這種分頁功能,平時很常見,不過需要自己動手做的需求卻很少,所以一直停留在知道應該就是那麼回事,但實際上自己從來沒怎麼探究過的層面上,知道應該會涉及到一些邏輯判斷,不會實現起來應該沒什麼難度,然而,真的等到自己著手實現的時候,才知道什麼叫想得美。


簡單介紹

先上效果圖:

原生 JS實現一個簡單分頁外掛

有點類似於 Github搜尋結果頁的底部分頁,可能部分邏輯有點出入,但總體應該差不多

程式碼使用 ES6語法,這個外掛其實是一個 classbabel打包後可相容到 IE9,原生js無任何依賴。

整個外掛類程式碼 SimplePagination加上空行註釋什麼的共約 200行左右,不過其中有部分程式碼是輔助程式碼,例如初始化、選擇器、增刪類等方法,再除去空行註釋,最後剩下的核心程式碼也就不到 100行的樣子。

主要的判斷邏輯都在 gotoPage這個方法中,因為需要考慮到各種情況,所以裡面寫了很多的 if.. else...判斷,沒寫下這些程式碼之前,我覺得這個東西充其量也就幾個判斷差不多了,但是沒想到會有這麼多,每次的頁碼切換都對應著不同的判斷分支,比較繁瑣。


核心程式碼簡要分析

核心方法是 gotoPage,乍一看,此方法中到處都是 if...else..判斷,似乎無從下手,但是不論頁碼如何變,也不管是如何切換到某個頁碼的,只需要記住一點,那就是切換到某個頁碼時,這個頁碼對應的整個分頁元件的狀態是確定的,這一點很重要,只要把握住了這點,那一連串的 if...else...判斷的意義其實也就清晰了。

此方法最外層的一個 if...else...判斷是針對頁碼是否需要顯示省略號佔位符的,如果頁碼總數小於頁面上課同時存在的頁碼數,那麼就不需要省略符號佔位了,就是一種比較簡單的分頁,例如下面這種:

原生 JS實現一個簡單分頁外掛

對於這種情況,只需要在切換頁碼的時候,變換 active的頁碼即可。

至於另外那種需要省略號佔位的情況,才是複雜的地方,而這個分支裡,最外層有 3個判斷,這 3個判斷包括了所有頁碼切換的情況。

第一個判斷是針對分頁元件左邊不需要出現省略號佔位符的情況,例如下面這種:

原生 JS實現一個簡單分頁外掛

第二個判斷是針對分頁元件右邊不需要出現省略號佔位符的情況,例如下面這種:

原生 JS實現一個簡單分頁外掛

第三個判斷是針對分頁元件兩邊都需要出現省略號佔位符的情況,例如下面這種:

原生 JS實現一個簡單分頁外掛

整個分頁元件的所有狀態,肯定都被包括在這三種狀態中,所以接下來的邏輯判斷只需要針對這三個狀態就行了。


用法

首先 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結構,我在示例程式碼中隨便寫了個樣式,如果你不喜歡這個樣式完全可以自己重寫。

相關文章