html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>分页器</title>
<link href="pager.css" rel="stylesheet"/>
</head>
<body>
<div id="pager"></div>
<script src="pager.js"></script>
<script>
function doChangePage(obj){
//TO DO
}
var pagerBox = document.getElementById('pager');
var pager = new Pager({
index: 1,
total: 15,
parent: pagerBox,
onchange: doChangePage
});
</script>
</body>
</html>
css代码:
.pager-box:after{
display:block;
height:0;
visibility:hidden;
clear:both;
content:'';
}
.pager{
float:left;
position:relative;
left:50%;
font-family:微软雅黑;
}
.pager a,.pager span{
position:relative;
left:-50%;
display:block;
float:left;
margin-left:5px;
border:1px solid #b6bcc1;
padding: 5px 10px;
text-decoration:none;
color:#b6bcc1;
border-radius:3px;
}
.pager span{
border:0;
}
.pager a.js-selected{
background:#b6bcc1;
color:#fff;
cursor:default;
}
.pager a.js-disabled{
background:#f1f1f1;
border-color:#f1f1f1;
cursor:default;
color:#fff;
}
pager.js代码
(function(window, undefined){
/**
* 创建元素节点并返回
*/
function create(tagName, className, parent){
var element = document.createElement(tagName);
element.className = className;
parent.appendChild(element);
return element;
}
/**
* 数组消除重复
*/
function clearRepeat(arr){
var obj = {},
result = [];
for(var i = 0, len = arr.length; i < len; i++){
obj[arr[i]] = 1;
}
for(var i in obj){
result.push(i);
}
return result;
}
/**
* 添加类名
*/
function addClassName(element, className){
var aClass = element.className.split(' ');
aClass.push(className);
aClass = clearRepeat(aClass);
element.className = aClass.join(' ');
}
/**
* 删除类名
*/
function delClassName(element, className){
var aClass = element.className.split(' '),
index = aClass.indexOf(className);
if(index > 0) aClass.splice(index, 1);
element.className = aClass.join(' ');
}
/**
* 检查是否含有类名
* @param element
* @param className
* @returns {boolean}
*/
function hasClassName(element, className){
var aClass = element.className.split(' '),
index = aClass.indexOf(className);
if(index > 0) return true;
return false;
}
var Pager = function(obj){
this.__total = obj.total || 1;
this.__index = obj.index || 1;
this.__parent = obj.parent;
this.__onchange = obj.onchange;
//初始化分页器
this.__init(obj);
};
var pro = Pager.prototype;
/**
* 初始化分页器
*/
pro.__init = function(obj){
if(this.__total < this.__index) return;
//存储数字
this.__numbers = [];
//储存省略号
this.__dots = [];
this.__wrapper = create('div', 'pager-box', this.__parent);
this.__body = create('div', 'pager', this.__wrapper);
//存储上一页
this.__preBtn = create('a', 'prev', this.__body);
this.__preBtn.href = 'javascript:void(0);';
this.__preBtn.innerText = (obj.label && obj.label.prev) || '上一页';
//存储数字
if(this.__total < 8){
for(var i = 0; i < this.__total; i++){
var t = create('a', 'number', this.__body);
t.href = 'javascript:void(0);';
t.innerText = i + 1;
this.__numbers.push(t);
}
}else{
for(var i = 0; i < 2; i++){
var t = create('span', 'dots', this.__body);
t.innerText = '...';
this.__dots.push(t);
};
for(var i = 0; i < 7; i++){
var t = create('a', 'number', this.__body);
t.href = 'javascript:void(0);';
this.__numbers.push(t);
}
}
//存储下一页
this.__nextBtn = create('a', 'next', this.__body);
this.__nextBtn.href = 'javascript:void(0);';
this.__nextBtn.innerText = (obj.label && obj.label.next) || '下一页';
//
this._$setIndex(this.__index);
//
this.__body.onclick = this.__doClick.bind(this);
};
pro.__doClick = function(e){
var e = e || window.event,
target = e.target || e.srcElement;
//点击省略号
if(target.tagName.toLowerCase() == 'span') return;
//点击了不能点击的上一页或者下一页
if(hasClassName(target, 'js-disabled')) return;
//点击了当前页
if(hasClassName(target, 'js-selected')) return;
if(target == this.__preBtn){
//点击了上一页
this._$setIndex(this.__index - 1);
}else if(target == this.__nextBtn){
//点击了下一页
this._$setIndex(this.__index + 1);
}else{
//点击了数字
var index = target.innerText;
this._$setIndex(index);
}
};
/**
* 跳转页数
*/
pro._$setIndex = function(index){
index = parseInt(index);
//更新信息
if(index != this.__index){
this.__last = this.__index;
this.__index = index;
}
//处理
delClassName(this.__preBtn, 'js-disabled');
delClassName(this.__nextBtn, 'js-disabled');
if(this.__total < 8){
//总页数小于8的情况
if(this.__last) delClassName(this.__numbers[this.__last - 1], 'js-selected');
addClassName(this.__numbers[this.__index - 1], 'js-selected');
if(this.__index == 1) addClassName(this.__preBtn, 'js-disabled');
if(this.__index == this.__total) addClassName(this.__nextBtn, 'js-disabled');
}else{
this.__dots[0].style.display = 'none';
this.__dots[1].style.display = 'none';
for(var i = 0; i < 7; i++){
delClassName(this.__numbers[i], 'js-selected');
};
if(this.__index < 5){
for(var i = 0; i < 6; i++){
this.__numbers[i].innerText = i + 1;
}
this.__numbers[6].innerText = this.__total;
this.__dots[1].style.display = 'block';
this.__body.insertBefore(this.__dots[1], this.__numbers[6]);
addClassName(this.__numbers[this.__index - 1], 'js-selected');
if(this.__index == 1) addClassName(this.__preBtn, 'js-disabled');
}else if(this.__index > this.__total - 4){
for(var i = 1; i < 7; i++){
this.__numbers[i].innerText = this.__total + i -6;
}
this.__numbers[0].innerText = '1';
this.__dots[0].style.display = 'block';
this.__body.insertBefore(this.__dots[0], this.__numbers[1]);
addClassName(this.__numbers[this.__index + 6 - this.__total], 'js-selected');
if(this.__index == this.__total) addClassName(this.__nextBtn, 'js-disabled');
}else{
this.__numbers[0].innerText = '1';
for(var i = 1; i < 6; i++){
this.__numbers[i].innerText = this.__index - 3 + i;
if(i == 3) addClassName(this.__numbers[i], 'js-selected');
}
this.__numbers[6].innerText = this.__total;
this.__dots[0].style.display = 'block';
this.__body.insertBefore(this.__dots[0], this.__numbers[1]);
this.__dots[1].style.display = 'block';
this.__body.insertBefore(this.__dots[1], this.__numbers[6]);
}
}
if(typeof this.__onchange == 'function'){
this.__onchange({
index: this.__index,
last: this.__last,
total: this.__total
})
}
};
/**
* 得到总页数
*/
pro._$getIndex = function(){
return this.__index;
};
/**
* 得到上一个页数
*/
pro._$getLast = function(){
return this.__last;
};
//变成全局
window.Pager = Pager;
})(window);
主要思路:
分页器共分为以下4种情况:
情况1,当total < 8 时,所有的页码全部显示。
情况2,当total >= 8 且 index < 5时,显示1-6和最后一页。
情况3,当total >= 8 且 index > total - 4时,显示1和最后6项。
情况4,当total >= 8 且 5 <= index <= total - 4时,显示1和最后一页,和中间5项。
Pager类实例化时传入一个设置对象:
{
parent: element, //给分页器设置父节点
index: index, //设置当前页
total: total, //设置总页数
onchange: function(){} //页数变化回调函数
}
当我们实例化Pager时,执行Pager函数体内的语句,首先赋值,然后就执行初始化函数:
var Pager = function(obj){
//赋值
this.__total = obj.total || 1;
this.__index = obj.index || 1;
this.__parent = obj.parent;
this.__onchange = obj.onchange;
//初始化分页器
this.__init(obj);
};
初始化函数this.__init结构:
Pager.prototype.__init = function(obj){
(根据上面分析的情况进行处理)
...
this._$setIndex(this.__index); //跳转到初始页
//绑定分页器点击函数
this.__body.onclick = this.__doClick.bind(this);
};
初始化完成,点击后就会做出相应的判断,并使用this._$setIndex(index)进行跳转