原生 JS实现一个简单分页插件

9,739 阅读5分钟

最近做的一个 PC端的需求,这个需求中有一个小点,页面底部有一块列表区域,这个列表的数据量比较大,需要进行分页控制,切换页码的时候,发送一个 ajax请求,在页面无刷新的情况下,实现列表数据的刷新,所以就涉及到了前端分页功能,到网上看了一圈,发现那些开源的相关插件要么有各种依赖,要么太复杂用不上,要么上手有点困难,所以就想着应该也不太难,自己写个得了。

关于这种分页功能,平时很常见,不过需要自己动手做的需求却很少,所以一直停留在知道应该就是那么回事,但实际上自己从来没怎么探究过的层面上,知道应该会涉及到一些逻辑判断,不会实现起来应该没什么难度,然而,真的等到自己着手实现的时候,才知道什么叫想得美。


简单介绍

先上效果图:

有点类似于 Github搜索结果页的底部分页,可能部分逻辑有点出入,但总体应该差不多

代码使用 ES6语法,这个插件其实是一个 classbabel打包后可兼容到 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说明是否必填
containerstringbody一个DOM元素的选择器,id 或者 class均可,表示分页的容器
maxShowBtnCountnumber5不包括开头和结尾的两个固定按钮外,中间最多展示几个数字页码按钮
pCNamestringpage-li所有的分页页码元素的统一类名,包括上一页、下一页
activeCNamestringpage-active当选中页码时添加的类名class
dataNumberAttrstring页码元素上的一个属性,其值为页码元素所表示的页码data-number
prevCNamestringpage-prev上一页 按钮的类名class
nextCNamestringpage-next下一页 按钮的类名class
disbalePrevCNamestringno-prev禁用 上一页 按钮的可用性时给此按钮添加的类名class
disbaleNextCNamestringno-next禁用 下一页 按钮的可用性时给此按钮添加的类名class
pageNumberCNamestringpage-number不包括 上一页 下一页、省略号占位符按钮之外的所有页码元素统一类名
swEventstringclick触发切换页面的事件
onPageChangestring-页码切换时的回调函数

除了根据页面上的页码和上一页、下一页按钮进行页码切换外,插件还有一个 gotoPage方法可用,此方法接收一个类型为 number的参数,调用此方法,就会跳到此参数指定的页码上,例如,跳转到页码 9上:

slp.gotoPage(9)

如果传入的参数不是合法的页码,则不会进行任何操作。

本文的可运行示例代码已经放到 Github上了,有兴趣的可以看下~

SimplePagination这个类主要在于页码切换的逻辑判断,外加简单地组装了 DOM结构,我在示例代码中随便写了个样式,如果你不喜欢这个样式完全可以自己重写。