ES6学习-封装一个分页插件

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
    })
}

ES6学习-封装一个分页插件

 

上一篇:JavaScript 算法 1_2 先进先出队列 (链表实现)


下一篇:JavaScript 算法 1_1 下压堆栈 (链表实现)