基于JQ封装的分页插件

604 阅读2分钟

最近写了有一段时间JQ,做列表分页之类的项目太多,于是把分页封装了一个简单的组件,具体的封装如下。

扩展JQ的静态方法

HTML部分

<ul class="pagination"></ul>

CSS部分

.pagination {
    /* display: -webkit-flex;
    display: flex; */
    display: none;
    justify-content: flex-end;
    list-style: none;
    overflow: hidden;
    font-size: 14px;
}
.pagination li {
    padding: 6px 10px;
    line-height: 1.5;
    border: 1px solid #e0e0e0;
    border-right: none;
    cursor: pointer;
}
.pagination li:last-of-type {
    border-right: 1px solid #e0e0e0;
}
.pagination li a {
    text-decoration: none;
}
.pagination li a:link,
.pagination li a:hover,
.pagination li a:visited,
.pagination li a:active {
    color: #666666;
}
.pagination li.active a {
    color: #c2e2f1;
}
.pagination li.disable {
    pointer-events: none;
    cursor: default;
}

js部分

;(function($, window, undefined) {
    var totPage = '', 
        curPage = '';

    var defaultOpts = {
        container: '.pagination',
        totalLists: null,   //需要和pageSize组合使用
        pageSize: 10,
        totalPage: null,    //可单独使用,不传totalLists、pageSize
        currentPage: 1,
        disabledColor: '#666',
        normalColor: '#000',
        callBack: null,
    }

    var Pagination = function(opts){
        this.settings = $.extend({},defaultOpts,opts);
        totPage = this.settings.totalPage 
                  || Math.ceil(this.settings.totalLists/this.settings.pageSize);
        curPage = this.settings.currentPage;
        this.init();
    }

    Pagination.prototype = {
        init: function(){
            this.creatPage(totPage,curPage);
            this.bindEvent();
        },
        creatPage: function(totPage,curPage){ 
            var _this = this,
                _container = $(_this.settings.container);

            // 小于1页时隐藏分页组件
            if(totPage <= 1){
                _container.hide();
                return;
            }

            // 判断中间需要展示的页码数是从多少开始到多少结束
            _container.children('li').remove();
            // 获取当前页,根据当前页 计算 需要显示的页码(最多显示5个页码,
            // 假定当前的是中间一个,前后各两个,检查前后两个是否超出边界)
            var startIndex = curPage - 2; //组件开始展示的页码
            var endIndex = curPage + 2;  //组件结束展示的页码
            // 超出修正
            if (startIndex < 1) { //开始展示的页码小于1,即当前页小于3
                startIndex = 1; //开始页重置为1
                 //结束页设置为 x+4(总共展示五个页码数,当前页码后面最多展示4个页码数)
                endIndex = startIndex + 4;
            }
            if (endIndex > totPage) { //假定展示的结束页码数大于总页码数
                endIndex = totPage; //结束页重置为总页码数
                //结束页码数倒推4个页码数大于0,即开始展示的页码数为 x-4,否则重置为1
                startIndex = (endIndex-4) > 0 ? endIndex-4 : 1; 
            }

            // 生成页码
            var $li = '<li data-page="1">首页</li>';
            // 生成前面可能的…
            if(startIndex>=2 && totPage>5){
                $li += '<li class="disable"><a href="#">…</a></li>';
            }
            for (var i = startIndex; i <= endIndex; i++) {
                // 高亮当前页,生成中间展示的页码数
                if (i == curPage) { //当前页
                    $li += '<li class="active disable" data-page="' + i + '"><a href="#">' + i + '</a></li>';
                }else{ //非当前页
                    $li += '<li  data-page="' + i + '"><a href="#">' + i + '</a></li>';
                }
            }
            // 生成后面可能的…
            if(curPage+2<totPage && totPage>5){
                $li += '<li class="disable"><a href="#">…</a></li>';
            }
            $li += '<li data-page="">尾页</li>';
            // 添加到ul中
            _container.html($li);
            _this.refreshStyle();
        },
        bindEvent: function(){
            var _this = this,
                _container = $(_this.settings.container),
                _fn = function(){
                    curPage = +$(this).attr('data-page');
                    _this.settings.currentPage = curPage;
                    if($.isFunction(_this.settings.callBack)){
                        //把当前页码数传出去给回调函数使用
                        _this.settings.callBack(_this.settings.currentPage);
                        _container.off('click','li',_fn);   //解绑事件
                    }
                };
            _container.on('click','li',_fn);
        },
        // 处理首页、尾页按钮样式
        refreshStyle: function(){
            var _this = this,
                _container = $(_this.settings.container),
                _firstLi = _container.children('li:first'),
                _lastLi = _container.children('li:last');
            if(curPage == 1){
                _firstLi.css({'color':_this.settings.disabledColor,'pointer-events':'none'});
            }else{
                _firstLi.css({'color':_this.settings.normalColor,'pointer-events':'auto'});
            }
            if(curPage == totPage){
                _lastLi.css({'color':_this.settings.disabledColor,'pointer-events':'none'});
            }else{
                _lastLi.css({'color':_this.settings.normalColor,'pointer-events':'auto'});
            }
            _lastLi.attr('data-page',totPage).end()
                   .css({'display':'-webkit-flex', 'display':'flex'});
        }
    }

    var paginationInit = function(opts){
        return new Pagination(opts);
    }

    window.paginationInit = $.paginationInit = paginationInit;
  })(jQuery, window, undefined);

插件调用

$.paginationInit({
    container: '.pagination',
    totalLists: 100,      //总条数
    totalPage: 10,
    pageSize: 10,
    currentPage: 1,
    callBack: function(cur){
        // fn();   //要执行的函数(可以为查询列表函数,查询成功后调用分页组件)
        console.log('currentPage',cur);
    }
});

扩展JQ实例的方法

;(function($, window, undefined) {
    var totPage = '', 
        curPage = '';

    var Pagination = function(el, opts){
        this.$el = el;
        this.defaultOpts = {
            totalLists: null,   //需要和pageSize组合使用
            pageSize: 10,
            totalPage: null,    //可单独使用,不传totalLists、pageSize
            currentPage: 1,
            disabledColor: '#666',
            normalColor: '#000',
            callBack: null,
        }
        this.settings = $.extend({},this.defaultOpts,opts);
        totPage = this.settings.totalPage 
                  || Math.ceil(this.settings.totalLists/this.settings.pageSize);
        curPage = this.settings.currentPage;
    }

    Pagination.prototype = {
        init: function(){
            this.creatPage(totPage,curPage);
            this.bindEvent();
        },
        creatPage: function(totPage,curPage){ 
            var _this = this,
                _el = this.$el;

            // 小于1页时隐藏分页组件
            if(totPage <= 1){
                _el.hide();
                return;
            }

            // 判断中间需要展示的页码数是从多少开始到多少结束
            _el.children('li').remove();
            // 获取当前页,根据当前页 计算 需要显示的页码(最多显示5个页码,
            // 假定当前的是中间一个,前后各两个,检查前后两个是否超出边界)
            var startIndex = curPage - 2; //组件开始展示的页码
            var endIndex = curPage + 2;  //组件结束展示的页码
            // 超出修正
            if (startIndex < 1) { //开始展示的页码小于1,即当前页小于3
                startIndex = 1; //开始页重置为1
                //结束页设置为 x+4(总共展示五个页码数,当前页码后面最多展示4个页码数)
                endIndex = startIndex + 4;  
            }
            if (endIndex > totPage) { //假定展示的结束页码数大于总页码数
                endIndex = totPage; //结束页重置为总页码数
                //结束页码数倒推4个页码数大于0,即开始展示的页码数为 x-4,否则重置为1
                startIndex = (endIndex-4) > 0 ? endIndex-4 : 1; 
            }

            // 生成页码
            var $li = '<li data-page="1">首页</li>';
            // 生成前面可能的…
            if(startIndex>=2 && totPage>5){
                $li += '<li class="disable"><a href="#">…</a></li>';
            }
            for (var i = startIndex; i <= endIndex; i++) {
                // 高亮当前页,生成中间展示的页码数
                if (i == curPage) { //当前页
                    $li += '<li class="active disable" data-page="' + i + '"><a href="#">' + i + '</a></li>';
                }else{ //非当前页
                    $li += '<li  data-page="' + i + '"><a href="#">' + i + '</a></li>';
                }
            }
            // 生成后面可能的…
            if(curPage+2<totPage && totPage>5){
                $li += '<li class="disable"><a href="#">…</a></li>';
            }
            $li += '<li data-page="">尾页</li>';
            // 添加到ul中
            _el.html($li);
            _this.refreshStyle();            
        },
        bindEvent: function(){
            var _this = this,
                _el = this.$el;
            var _fn = function(){
                curPage = +$(this).attr('data-page');
                _this.settings.currentPage = curPage;
                if($.isFunction(_this.settings.callBack)){
                    //把当前页码数传出去给回调函数使用
                    _this.settings.callBack(_this.settings.currentPage); 
                    _el.off('click','li',_fn);   //解绑事件
                }
            };
            _el.on('click','li',_fn);
        },
        // 处理首页、尾页按钮样式
        refreshStyle: function(){
            var _this = this,
                _el = this.$el,
                _firstLi = _el.children('li:first'),
                _lastLi = _el.children('li:last');
            if(curPage == 1){
                _firstLi.css({'color':_this.settings.disabledColor,'pointer-events':'none'});
            }else{
                _firstLi.css({'color':_this.settings.normalColor,'pointer-events':'auto'});
            }
            if(curPage == totPage){
                _lastLi.css({'color':_this.settings.disabledColor,'pointer-events':'none'});
            }else{
                _lastLi.css({'color':_this.settings.normalColor,'pointer-events':'auto'});
            }
            _lastLi.attr('data-page',totPage).end()
                   .css({'display':'-webkit-flex', 'display':'flex'});
        }
    }

    $.fn.paginationInit = function(opts){
        var pagination = new Pagination(this, opts);
        return pagination.init();
    }

  })(jQuery, window, undefined);

插件调用

$('.pagination').paginationInit({
    totalLists: 100,      //总条数
    totalPage: 10,
    pageSize: 10,
    currentPage: 1,
    callBack: function(cur){
    // fn();   //要执行的函数(可以为查询列表函数,查询成功后调用分页组件)
    console.log('currentPage',cur);
    }
});

2022年3月4日,现在对封装和js模式算是有一点点熟悉,看上面的封装,是传入了jQuery, window两个对象,window.paginationInit = $.paginationInit = paginationInit;分别给两个对象加上了一个paginationInit方法,该方法返回一个Pagination的实例。在返回的实例可以调用;(function($, window, undefined) {})(jQuery, window, undefined);这个立即执行函数中的私有变量,实例化Pagination时调用了init方法,init方法再执行其他方法。而第二种方法在;(function($, window, undefined) {})(jQuery, window, undefined);中声明了一些私有变量和类,最后用$.fn在jQuery的命名空间上,加上paginationInit方法,这会对每一个jQuery实例有效。paginationInit方法中new Pagination(this, opts)初始化一个Pagination实例,并传入当前jQuery实例作为第一个参数,最后调用该实例上的init方法。