HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>分页</title>
<script src="pagenation.js"></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="pagenation"></div>
</body>
<script type="text/javascript">
const p = new Pagenation(".pagenation", {
totalpage: 13,
change: function(current) {
console.log("当前页:" + current)
}
});
console.info(p);
</script>
</html>
pagenation.js
class Pagenation {
constructor(ele, options = {}) {
this.ele = document.querySelector(ele)
// 设置默认值
this.default = {
width:options.width || '800px',// 最外层容器宽度
height:options.height || '60px',// 最外层容器高度
current: options.current || 1, // 当前是第几页
total: options.total || 100, // 一共多少条数据
totalpage: options.totalpage || 10, // 总共多少页
pagesize: options.pagesize || 10, // 一页显示多少条数据
first: options.first || '首页', // 首页显示的文字
prev: options.prev || '上一页', // 上一页显示的文字
next: options.next || '下一页', //下一页显示的文字
last: options.last || '最后一页', // 最后一页显示的文字
go: options.go || '跳转', // 跳转显示的文字
styles: options.styles || {}, // 用户给传入的自定义样式
change:options.change || (()=>{})// 回调函数
}
// 默认的按钮样式
this.btnsCSS = {
border: '0.5px solid rgba(128,128,128,.8)',
display : 'flex',
justifyContent:'center',
alignItems:'center',
padding:'3px',
margin:'5px',
cursor:'pointer',
borderRadius:'4px',
backgroundColor : '#f4f4f5',
color:'#606266',
fontSize:'13px',
textAlign:'center',
minWidth: '24px',
minHeight:'22px'
}
// ...的按钮样式
this.pointCSS = {
border: '0.5px solid transparent',
display : 'flex',
justifyContent:'center',
alignItems:'center',
padding:'3px',
margin:'5px',
borderRadius:'4px',
backgroundColor : 'transparent',
color:'#606266',
fontSize:'13px',
textAlign:'center',
minWidth: '24px',
minHeight:'22px'
}
this.init()
}
init() {
this.renderHtml()
this.setBoxStyle()
this.bindEvent()
}
/**
* 渲染DOM结构
*/
renderHtml() {
const { first , prev , next ,last , current , totalpage } = this.default
const frg = document.createDocumentFragment()
// 注意:添加元素的结构顺序。
// 1.创建'首页'
const firstEle = _setCSS( _creEle("div",'first',first) , this.btnsCSS)
frg.appendChild(firstEle)
if(current === 1){
_setCursorStatus(firstEle,'no-drop')
}
// 2.创建'上一页'
const prevEle = _setCSS( _creEle("div",'prev',prev) ,this.btnsCSS)
frg.appendChild(prevEle)
if(current === 1){
_setCursorStatus(prevEle,'no-drop')
}
// 3.单独创建中间的按钮
const listEle = _setCSS( _creEle("div",'list','') ,{
border :0,
padding :0,
display : 'flex',
justifyContent:'flex-start',
alignItems:'center'
})
listEle.appendChild(this.creListItem())
frg.appendChild(listEle)
// 4.创建'下一页'
const nextEle = _setCSS( _creEle("div",'next',next) ,this.btnsCSS)
frg.appendChild(nextEle)
if(current === totalpage){
_setCursorStatus(nextEle,'no-drop')
}
// 5.创建'最后一页'
const lastEle = _setCSS( _creEle("div",'last',last) ,this.btnsCSS)
frg.appendChild(lastEle)
if(current === totalpage){
_setCursorStatus(lastEle,'no-drop')
}
// 6.单独创建跳转
const jumpEle = _setCSS( _creEle("div",'jump','') ,{
border :0,
padding :0,
display : 'flex',
justifyContent:'flex-start',
alignItems:'center'
})
jumpEle.appendChild(this.creJumpItem())
frg.appendChild(jumpEle)
// 最后放入ele中
this.ele.innerHTML = ''
this.ele.appendChild(frg)
// 回调函数
this.default.change(current)
// 在每次渲染完成后,为input框绑定回车事件
this.myinput = this.ele.querySelector(".jump input")
this.bindKeyPressEvent()
}
creListItem(){
const {current , totalpage} = this.default
const frg = document.createDocumentFragment();
// 小于10的时候直接渲染
if(totalpage <= 10){
for(let i = 1; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
return frg
}
// 准备一个...
const point = _setCSS( _creEle('p', 'ignore', '...') , this.pointCSS)
// 当总页数 >9 的时候
// 当current < 5 的时候,1 2 3 4 5 6 ... 98 99 100
if(current < 5){
for(let i = 1; i <= 6; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = totalpage - 2; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
return frg
}
// 当current ==5 的时候, 1 2 3 4 current 6 7 ... 99 100
if(current === 5 ){
for(let i = 1; i <= 7; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = totalpage - 1; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
return frg
}
// 当current >5 && current < 倒数第五个的时候,1 2 ... 6 current 8 9 ... 99 100
if(current > 5 && current < totalpage - 4){
for(let i = 1; i <= 2; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = current-1; i <= current+2; i ++ ){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = totalpage - 1; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
return frg
}
// 当current == 倒数第五个的时候,1 2 ... 94 95 current 97 98 99 100
if(current === totalpage - 4){
for(let i = 1; i <= 2; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = totalpage - 6; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
return frg
}
// 当current > 倒数第五个的时候,1 2 ... 94 95 current 97 98 99 100
if(current > totalpage - 4){
for(let i = 1; i <= 2; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
frg.appendChild(p)
}
// 加个...
frg.appendChild(point.cloneNode(true))
for(let i = totalpage - 6; i <= totalpage; i ++){
const p = _setCSS( _creEle("p",'item',i) ,this.btnsCSS)
p.dataset.index = i
if(i === current){
_setCSS(p,{
backgroundColor : '#409eff',
color:'#fff'
})
}
frg.appendChild(p)
}
return frg
}
}
creJumpItem(){
const { go , current } = this.default
const frg = document.createDocumentFragment()
// 创建input框
const inp = document.createElement("input")
inp.value = current
_setCSS(inp, {
minWidth: '24px',
minHeight:'22px',
outline: 'none',
margin: '5px',
width: '45px',
height:'24px',
cursor:'pointer'
})
frg.appendChild(inp)
// 创建button
const btn = _creEle("button", 'go', go)
_setCSS(btn, {
border: '0.5px solid rgba(128,128,128,.8)',
display : 'flex',
justifyContent:'center',
alignItems:'center',
padding:'5px',
margin:'5px',
cursor:'pointer',
borderRadius:'4px',
backgroundColor : 'rgb(64, 158, 255)',
color:'rgb(255, 255, 255)',
fontSize:'13px',
textAlign:'center',
minWidth: '24px',
minHeight:'22px',
outline: 'none'
})
frg.appendChild(btn)
return frg
}
setBoxStyle(){
const { width , height } = this.default
_setCSS(this.ele, {
width,
height,
display:'flex',
justifyContent:'flex-start',
alignItems:'center'
})
}
bindEvent(){
this.ele.addEventListener('click',e => {
e = e ||window.event
const target = e.target ||window.srcElement
// 拿到类名
const className = target.className
//console.log(className)
const { current, totalpage } = this.default
switch (className){
case 'next': // 下一页
if(current < totalpage){
this.default.current++
this.renderHtml()
}
break;
case 'prev':// 上一页
if(current > 1){
this.default.current--
this.renderHtml()
}
break;
case 'first':// 首页
if(current > 1){
this.default.current = 1
this.renderHtml()
}
break;
case 'last':// 最后一页
if(current < totalpage){
this.default.current = totalpage
this.renderHtml()
}
break;
case 'item':// 点击按钮
// 字符串变数字
const index = target.dataset.index - 0
if(index === current){break}
//console.log(index)
this.default.current = index
this.renderHtml()
break;
case 'go':// 点击跳转按钮
// 拿到input的值,字符串变数字
let goIndex = target.previousElementSibling.value - 0
if(goIndex === current){break}
if(goIndex <= -1){goIndex = 1}
if(goIndex >= totalpage){goIndex = totalpage}
this.default.current = goIndex
this.renderHtml()
break;
default:
break;
}
})
}
bindKeyPressEvent(){
this.myinput.addEventListener('keypress',(e)=>{
const eCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode
const { current, totalpage } = this.default
if (eCode == 13){
let goIndex = this.myinput.value - 0
if(goIndex === current){return}
if(goIndex <= -1){goIndex = 1}
if(goIndex >= totalpage){goIndex = totalpage}
this.default.current = goIndex
this.renderHtml()
}
})
}
}
/**
* 创建DOM结构
* @param {Object} nodeName
* @param {Object} className
* @param {Object} text
*/
function _creEle(nodeName, className, text) {
const ele = document.createElement(nodeName)
ele.className = className
// 使用innerHtml,用户可以使用字体图标之类的...
ele.innerHTML = text
return ele
}
/**
* 添加样式
* @param {Object} ele
* @param {Object} styles
*/
function _setCSS(ele, styles) {
for(let key in styles) {
ele.style[key] = styles[key]
}
return ele
}
function _setCursorStatus(ele,cursorStatus){
_setCSS(ele, {
cursor : cursorStatus
})
}
![](https://i-blog.csdnimg.cn/blog_migrate/41675e1153b3133c7e5a7556767820ae.png)