Jquery分頁元件

龍恩0707發表於2013-08-28

   最近工作不是很忙,所以就看看淘寶kissy分頁元件原始碼,感覺程式碼也不怎麼難 容易理解,所以就按照他們的思路自己重新理一遍,來加深自己對他們的理解,同時對他們的分頁元件進行一些重構(因為他們分頁是做好了,但是不能直接拿來用,所以就封裝了下),所以就用jquery封裝了一個。

     配置引數如下:

       影響分頁元件資訊展現的因素如下圖所示:

                            

     元件提供以下配置引數: totalPage總頁數,預設值為1currentPage初始選中的頁碼,預設值為1 firstPagesCount最前面的展現頁數,預設值為2, preposePagesCount當前頁的緊鄰前置頁數,預設值為2 postposePagesCount當前頁的緊鄰後置頁數,預設值為1, lastPagesCount最後面的展現頁數,預設值為0 render是否自動渲染元件,預設值為true。

   對外公開的方法:

    render():  渲染元件

    show():    顯示元件

    hide():     隱藏元件

    destory():  銷燬元件

   頁碼顯示及對應的HTML結構渲染問題:

    一: 當前“選中的頁”前面HTML結構渲染的方式如下:

          判斷當前選中的頁碼 如果小於或者等於 (最前面的展示頁數 + 當前頁的緊鄰前置頁數 +1)的話

            if (currentPage <= firstPagesCount + preposePagesCount + 1) {
              
                for(var i=1; i<currentPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }

         這種情況下:對應的描述圖如下:

          

   對應的HTML結構程式碼如:  

       那麼否則的話         // 對應圖3

  else {
                for(var i=1; i<= firstPagesCount; i++) {
                    pageHTML += self._renderActivePage(i);
                }
                pageHTML += '<span class="pagination-break">...</span>';
                for(var i = currentPage-preposePagesCount; i <= currentPage-1; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }  

           那麼對應的描述圖如這樣的:

              圖3:

      

         渲染HTML結構:

        

        接著 就是當前選中的頁 html結構

  // 當前頁的頁碼 html顯示
        pageHTML += '<span class="pagination-curr">' + currentPage + '</span>';

   

 二: 當前頁頁碼後面的html展示 

  如果當前頁 大於或者等於 (總頁數 - 最後面的展現頁數 - 當前頁的緊鄰後置頁數)的話 程式碼如下:

         if (currentPage >= totalPage - lastPagesCount - postposePagesCount) {
                offset = currentPage + 1;
                for(var i=currentPage+1; i<=totalPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }

      對應的圖如下:

    

     對應的HTML結構渲染如下:

    

     否則的話:程式碼如下

   else {
                for(var i=currentPage+1; i<= currentPage+postposePagesCount; i++) {
                    pageHTML += self._renderActivePage(i);
                }
                pageHTML += '<span class="pagination-break">...</span>';
                for(var i=totalPage-lastPagesCount+1; i<=totalPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }

   對應圖如下:

     

  對應的HTML結構渲染如下:

    

 最後判斷下一頁的顯示方式   程式碼如下:

   pageHTML += currentPage === totalPage ? '<span class="pagination-end"><span>下一頁</span></span>' : '<a class="pagination-next"><span>下一頁<span></a>';

 

Jquery所有的JS程式碼如下:

      
/**
 * fileoverview Jquery分頁元件
 * @param {selector} 分頁容器
 * @param {cfg} object 預設配置
 */

 var Pagination = (function(){

    function Pagination(selector,cfg){
        if(this instanceof Pagination) {

            // 匹配傳引數clickElem
            if($.isPlainObject(selector)){
                this.selector = selector;
            }else if(/^\./.test(selector)){
                this.selector = $(selector);
            }else if(/^#/.test(selector)){
                this.selector = $(selector);
            }else if($('.'+selector)){
                this.selector = $('.'+selector);
            }else {
                throw new Error('傳遞引數不符合!');
            }
        }else {
            new Pagination(selector,cfg);
        }
        
        cfg = $.extend(Pagination.config,cfg || {});
        this.config = cfg || {};
        
        // 初始化時候 預設選中的頁數
        $.isFunction(this.config.callback) && this.config.callback(this.config.currentPage);

        this._init();
        
    }

    Pagination.config = {
        
        // 總頁數
        totalPage:1,
        
        // 預設選中的頁數
        currentPage: 1,

        //當前頁最大緊鄰前置頁數(不包括最前面顯示頁數)
        preposePagesCount: 2,

        //當前頁的最大緊鄰後置頁數
        postposePagesCount: 1,

        // 第一個"..."前顯示的頁數
        firstPagesCount: 2,

        // 第二個"..."後顯示的頁數
        lastPagesCount: 0,
        
        render: true,

        callback: function(idx){}
    };
    Pagination.prototype = {
        
        _init: function(){
            
            var self = this;
            
            if(self.config.render === true){
                
                self.render();
            }
            
        },

        /* 渲染 */
        render: function(){
            
            var self = this;
            self._renderUI();
            
            self._bindUI();
        },
        _renderUI: function(){
            var self = this;
            self._resetPagination();
        },

        // 處理點選元素
        _bindUI: function(){
            
            var self = this;
            
            /*
             * 注意jquery1.9 沒有live這個方法 所以在jquery1.9 API上會報錯 jquery1.9以上考慮用其他的繫結事件方法
             */
            $('.pagination-spec').live('click',function(e){
                var target = e.target,
                    toPage = $(target).attr('data-page') * 1;
                self._switchToPage(toPage);
            });
            $('.pagination-prev').live('click',function(e){
                var toPage = self.config.currentPage - 1;
                self._switchToPage(toPage);
            });
            $('.pagination-next').live('click',function(e){
                var toPage = self.config.currentPage + 1;
                self._switchToPage(toPage);
            });
        },
        _switchToPage: function(page){
            var self = this;
            self.config.currentPage = page;
            self._resetPagination();
            
            // 頁面顯示成功後 回撥
            $.isFunction(self.config.callback) && self.config.callback(self.config.currentPage);
        },
        /*
         * 重新整理分頁
         */
        _resetPagination: function(){
            
            var self = this,
                pageHTML = '',
                totalPage = self.config.totalPage > 0 ? self.config.totalPage : 1,
                currentPage = (self.config.currentPage <= totalPage) && (self.config.currentPage > 0) ? self.config.currentPage : 1,
                preposePagesCount = self.config.preposePagesCount >=0 ? self.config.preposePagesCount : 2,
                postposePagesCount = self.config.postposePagesCount >=0 ? self.config.postposePagesCount : 1,
                firstPagesCount = self.config.firstPagesCount >=0 ? self.config.firstPagesCount : 2,
                lastPagesCount = self.config.lastPagesCount >=0 ? self.config.lastPagesCount : 0,
                offset;
            // 當前頁碼顯示
            pageHTML += currentPage === 1 ? '<span class="pagination-start"><span>上一頁</span></span>' :
            '<a class="pagination-prev"><span>上一頁</span></a>';
            
            //當前頁的 前面html結構顯示問題
            if (currentPage <= firstPagesCount + preposePagesCount + 1) {
                
                for(var i=1; i<currentPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }

            }else {
                for(var i=1; i<= firstPagesCount; i++) {
                    pageHTML += self._renderActivePage(i);
                }
                pageHTML += '<span class="pagination-break">...</span>';
                for(var i=currentPage-preposePagesCount; i<=currentPage-1; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }
            // 當前頁的頁碼 html顯示
            pageHTML += '<span class="pagination-curr">' + currentPage + '</span>';

            // 當前頁頁碼後面的html展示
            if (currentPage >= totalPage - lastPagesCount - postposePagesCount) {
                offset = currentPage + 1;
                for(var i=currentPage+1; i<=totalPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }

            } else {
                for(var i=currentPage+1; i<= currentPage+postposePagesCount; i++) {
                    pageHTML += self._renderActivePage(i);
                }
                pageHTML += '<span class="pagination-break">...</span>';
                for(var i=totalPage-lastPagesCount+1; i<=totalPage; i++) {
                    pageHTML += self._renderActivePage(i);
                }
            }
            pageHTML += currentPage === totalPage ? '<span class="pagination-end"><span>下一頁</span></span>' :
                '<a class="pagination-next"><span>下一頁<span></a>';
            
            $(self.selector).html(pageHTML);
        },

        /**
            * @ 渲染可點選的頁碼
         * @param index {Number} 頁碼索引
         *
         */
        _renderActivePage: function(index) {
            return '<a class="pagination-spec" data-page="' + index + '">' + index + '</a>';
        },
        show: function(){
            var self = this;
            $(self.selector).show();
        },
        hide: function(){
            var self = this;
            $(self.selector).hide();
        },
        
        // 銷燬
        destory: function(){
            var self = this;
            $(self.selector) = null;

            // 銷燬用live繫結的事情
            $('.pagination-spec').die('click');
            $('.pagination-prev').die('click');
            $('.pagination-next').die('click');
        }
    };
    return Pagination;
 })();

     HTML呼叫方式如下:
     <div id = "Pagination"></div>
     <div id="content"></div>
     <script type="text/javascript">
         var intPageSize = 8, //一頁定義8條資料
             intRowCount = 100; //記錄總數
             intPageCount = Math.ceil(intRowCount/intPageSize);
         new Pagination('#Pagination',{
             totalPage: intPageCount,
             callback: function(idx){
                 console.log(idx);
             }
         });
     </script>
 
    其中一頁顯示多少條intPageSize 是使用者自定義的,
    記錄總數intRowCount  是後臺開發人員給的,
    總共多少頁 intPageCount  是我們要計算的。
    初始化方式如上 通過例項化。
    然後callback回撥函式 把相對應的 每頁顯示多少條intPageSize  
    和  相對應的頁碼 idx ajax方式傳參提交給開發人員  
    返回相應的資訊 我們渲染出來 就ok!

    css也放上來吧!如下

       <style>
        body {
            font: 12px/1.5 tahoma,arial,宋體b8b\4f53;
        }
        
        .pagination-start,
        .pagination-prev,
        .pagination-next,
        .pagination-end
        {
            width: 36px;
            background: url(http://img04.taobaocdn.com/tps/i4/T1cP85XihuXXXXXXXX-13-101.png) no-repeat;
        }
        .pagination-start,
        .pagination-prev,
        .pagination-next,
        .pagination-end,
        .pagination-spec,
        .pagination-curr,
        .pagination-break
        {
            min-width: 16px;
            _width: 16px;
            border: 1px solid #ccc;
            display: inline;
            float: left;
            height: 24px;
            margin-right: 3px;
            padding: 0 5px;
            line-height: 24px;
            text-align: center;
            font-family: Tahoma,SimSun,Arial;
            vertical-align: top;
            white-space: nowrap;
            overflow: hidden;
        }
        .pagination-start {
            padding-left: 16px;
            background-position: 5px 8px;
        }
         .pagination-prev {
            padding-left: 16px;
            background-position: 0 -12px;
        }
        .pagination-curr {
            font-weight: 700;
            color: #fd6d01;
            background-color: #ffede1;
            border: 1px solid #fd6d01;
        }
         .pagination-break {
            color: #c0c0c0;
            border: 0;
        }
         .pagination-next {
            padding-right: 16px;
            background-position: 42px -50px;
        }
        .pagination-end {
            padding-right: 16px;
            background-position: 47px -31px;
        }
        a {
            color: #36c;
            cursor: pointer;
        }
         a:hover {
            border: 1px solid #fd6d01;
        }
        
    </style>

 

 

相關文章