经常做信息管理类的网站,分页可以说是最常见的功能之一了。纵然网上可以找到一堆jquery分页插件,但我还是想手把手自己写一个分页,更清楚自己需要怎样的分页功能,不想包含过于复杂的功能。说到分页,我能想到3种:直接刷新页面;Ajax刷新分页;伪分页。伪分页其实就是对页面数据的过滤,页面包含了所有的数据的元素,只不过“一页”仅显示部分数据的元素。Ajax分页则是局部刷新页面上的数据元素。我先实现最简单的分页方式,即直接刷新页面。
jquery插件写法
jquery中提供了fn
扩展属性,任何写到fn
中的函数,都可以被jquery DOM元素直接调用。
1 | $.fn.sayHello = function(){ |
有了这个扩展函数,可以直接对元素这样$('#someElement').sayHello()
调用,也可以同时作用在多个元素上,像$('.some-class').sayHello()
这样。
注意sayHello
中两个this
是有区别的,函数进来的第一个this
就是指调用sayHello()
的元素,而且这里的this
就已经是jquery的元素了,不需要再多此一举$(this)
了。而this.each()
表示对所有调用sayHello()
的元素均进行如下操作。each(function(){})
里面的this
表示的是单个调用sayHello()
的元素,注意这里的this
是原生DOM元素,如要使用jquery的函数,则需要先$(this)
一下。
完善后的sayHello
代码如下。
1 | $.fn.sayHello = function(){ |
即这个sayHello插件会为元素绑定一个click
事件,点击后会弹出该元素的标签名。效果如下。
分页插件设计
令这个分页插件(扩展函数)叫做jqPagination
,我们希望它使用起来非常简单,在页面中只需要定义一个<div>
,无需定义任何子元素,只需要jqPagination()
一下,就会生成一个好看的分页按钮出来。由于页数是不确定的,不可能把所有页码在界面上都显示出来(体验太差),它只显示第一页、最后一页,以及当前页的前后两页。
可以看到,它有点类似一个“滑动窗口”,窗口大小是5(当前页和前后2页),未显示的页码用“…”显示。
由于在页面中只定义一个<div>
,那么当前的页码和总页数
要么写在
<div>
的自定义属性中要么当作参数传给
jqPagination
这就是这个分页插件的对外接口设计。<div>
中支持data-pn
和data-tpn
两个属性,分别表示当前页码和总页数。
1 | <div id="pagination1" data-pn="5" data-tpn="12"></div> |
同时jqPagination
也支持配置参数,如下。
1 | $('#pagination1').jqPagination({ |
插件实现
大体实现思路就是:
为
<div>
添加一些子元素,不涉及具体页码。生成带“滑动窗口”的具体页码,并为页码添加是否active的样式。
为每个页码添加链接,即点击该页则直接刷新页面。
为“前一页”和“后一页”绑定点击事件。
Step 1
1 | $.fn.jqPagination = function(options){ |
这里直接为几个特殊的元素占好“坑”,分别是:上一页,第1页,滑动窗口向前的省略,滑动窗口向后的省略,最后一页(页码为空),下一页。具体的页码元素都是有data-page
属性的,这里第一页和最后一页也属于具体页码。然后在Step 2中生成其他具体页码,并为这里占的“坑”设置active、disabled或hide。
Step 2
1 | var generatePages = function($el){ |
这里的滑动窗口的页码范围为Math.max(pn-2, 2)
到Math.min(pn+2, tpn-1)
,因为第1页和最后1页已经在Step 1中占好“坑”了。生成的具体页码即当前页的前后2页,添加好data-page
属性,插入到“坑”的相应位置。然后就是根据pn
(当前页码)和tpn
(总页数)对那些“坑”进行可见性的检查,该disabled的和该hide的。
Step 3 & 4
1 | var bindPageEvents = function($el){ |
这里就是为具体页码和“前一页”“后一页”添加点击效果。每个具体页码都是个带有href
属性的<a>
标签,以直接刷新页面,这里有个getPageHref
方法稍后描述。而点击“前一页”“后一页”实则是去找到相对于当前页的具体页码元素,然后调用targetClick
去模拟点击,也在稍后描述。
配置参数
除了前面提到的pn
和tpn
两个参数外,我们还需要添加两个参数。因为是直接刷新页面以获取新的分页数据,那url中肯定要有个参数表示页码,那么这个参数的key叫什么。我们提供一个默认的名字,就叫page
,即url都长成这样/some/to/?page=2
,当然这个参数的名字也可以自定义。还有就是,分页刷新页面默认就是当前的url,只不过page
参数的值不同,这个url也可以自定义。
1 | $.fn.jqPagination = function(options){ |
由此,前面提到的getPageHref
就是去替换url里的page
参数的值。
1 | var getPageHref = function(pageNo){ |
当然那个模拟点击页码的targetClick
就是直接刷新window.location.href
咯
1 | var targetClick = function($li){ |
插件使用
提供3种使用方式,最基本的就是
1 | <div id="pagination1" data-pn="5" data-tpn="12"></div> |
要手动设置pn和tpn,以及分页参数名称,就像这样
1 | $('#pagination2').jqPagination({ |
要自定义分页url的就像这样
1 | $('#pagination3').jqPagination({ |