一个分页插件的源码分析

简介:  /**  * This jQuery plugin displays pagination links inside the selected elements.  *  * This plugin needs at least jQuery 1.4.2  *  * @author Gabriel Birke (birke *at* d-scribe


/**

 * This jQuery plugin displays pagination links inside the selected elements.

 *

 * This plugin needs at least jQuery 1.4.2

 *

 * @author Gabriel Birke (birke *at* d-scribe *dot* de)

 * @version 2.2

 * @param {int}

 *            maxentries Number of entries to paginate

 * @param {Object}

 *            opts Several options (see README for documentation)

 * @return {Object} jQuery Object

 */

(function($) {

   /**

    * @class Class for calculating pagination values

     *

     * 下面的写法我的理解是定义一个我任务的构造方法,或者方法,或者对象

     * $.PaginationCalculator,这个$.PaginationCalculator对象中有两个参数

    */

   $.PaginationCalculator = function(maxentries, opts) {

      this.maxentries = maxentries;

      this.opts = opts;

   }

 

/**

 * 对这个对象进行扩展$.PaginationCalculator,为它添加numPages方法,getInterval方法。

 */

   $.extend($.PaginationCalculator.prototype, {

      /**

       * Calculate the maximum number of pages

       *

       * @method

       * @returns {Number}

         * 编写一个获得页码的方法

         *

       */

      numPages : function() {

         return Math.ceil(this.maxentries / this.opts.items_per_page);

      },

      /**

       * Calculate start and end point of pagination links depending on

       * current_page and num_display_entries.

       *

       * @returns {Array}

       */

      getInterval : function(current_page) {

         var ne_half = Math.floor(this.opts.num_display_entries / 2);

         var np = this.numPages();

         var upper_limit = np - this.opts.num_display_entries;

         var start = current_page > ne_half ? Math.max(Math.min(current_page

                - ne_half, upper_limit), 0) : 0;

         var end = current_page > ne_half ? Math.min(current_page + ne_half

                + (this.opts.num_display_entries % 2), np) : Math.min(

                this.opts.num_display_entries, np);

         return {

            start : start,

            end : end

         };

      }

   });

 

   // Initialize jQuery object container for pagination renderers,下面的方式是定义一个对象

   $.PaginationRenderers = {}

 

   /**

    * @class Default renderer for rendering pagination links

     *

     * 再次定义一个$.PaginationRenderers.defaultRenderer对象

    */

   $.PaginationRenderers.defaultRenderer = function(maxentries, opts) {

      this.maxentries = maxentries;

      this.opts = opts;

      this.pc = new $.PaginationCalculator(maxentries, opts);

   }

   $.extend($.PaginationRenderers.defaultRenderer.prototype,

                {

                   /**

                    * Helper function for generating a single link (or a

                    * span tag if it's the current page)

                    *

                    * @param {Number}

                    *            page_id The page id for the new item

                    * @param {Number}

                    *            current_page

                    * @param {Object}

                    *            appendopts Options for the new item: text

                    *            and classes

                    * @returns {jQuery} jQuery object containing the link

                    */

                   createLink : function(page_id, current_page, appendopts) {

                      var lnk, np = this.pc.numPages();

                      page_id = page_id < 0 ? 0 : (page_id < np ? page_id

                            : np - 1); // Normalize page id to sane

                                     // value

                      appendopts = $.extend( {

                         text : page_id + 1,

                         classes : ""

                      }, appendopts || {});

                      if (page_id == current_page) {

                         lnk = $("<a class='current'>" + appendopts.text

                               + "</a>");

                      } else {

                         lnk = $("<a>" + appendopts.text + "</a>").attr(

                               'href',

                               this.opts.link_to.replace(/__id__/,

                                     page_id));

                      }

                      if (appendopts.classes) {

                         lnk.addClass(appendopts.classes);

                      }

                      lnk.data('page_id', page_id);

                      return lnk;

                   },

                   // Generate a range of numeric links

                   appendRange : function(container, current_page, start,

                         end, opts) {

                      var i;

                      for (i = start; i < end; i++) {

                         this.createLink(i, current_page, opts)

                               .appendTo(container);

                      }

                   },

                   getLinks : function(current_page, eventHandler) {

                      var begin, end, interval = this.pc

                            .getInterval(current_page), np = this.pc

                            .numPages(), fragment = $("<div class='pagination'></div>");

 

                      // Generate "Previous"-Link

                      if (this.opts.prev_text

                            && (current_page > 0 || this.opts.prev_show_always)) {

                         fragment.append(this.createLink(

                               current_page - 1, current_page, {

                                  text : this.opts.prev_text,

                                  classes : "prev"

                               }));

                      }

                      // Generate starting points

                      if (interval.start > 0

                            && this.opts.num_edge_entries > 0) {

                         end = Math.min(this.opts.num_edge_entries,

                               interval.start);

                         this.appendRange(fragment, current_page, 0,

                               end, {

                                  classes : 'sp'

                               });

                         if (this.opts.num_edge_entries < interval.start

                               && this.opts.ellipse_text) {

                            $(

                                  "<span class='pagination-break'>"

                                        + this.opts.ellipse_text

                                        + "</span>").appendTo(

                                  fragment);

                         }

                      }

                      // Generate interval links

                      this.appendRange(fragment, current_page,

                            interval.start, interval.end);

                      // Generate ending points

                      if (interval.end < np

                            && this.opts.num_edge_entries > 0) {

                         if (np - this.opts.num_edge_entries > interval.end

                               && this.opts.ellipse_text) {

                            $(

                                  "<span class='pagination-break'>"

                                        + this.opts.ellipse_text

                                        + "</span>").appendTo(

                                  fragment);

                         }

                         begin = Math.max(np

                               - this.opts.num_edge_entries,

                               interval.end);

                         this.appendRange(fragment, current_page, begin,

                               np, {

                                  classes : 'ep'

                               });

 

                      }

                      // Generate "Next"-Link

                      if (this.opts.next_text

                            && (current_page < np - 1 || this.opts.next_show_always)) {

                         fragment.append(this.createLink(

                               current_page + 1, current_page, {

                                  text : this.opts.next_text,

                                  classes : "next"

                               }));

                     }

                      $('a', fragment).click(eventHandler);

                      return fragment;

                   }

                });

 

   // Extend jQuery,编写一个插件

   $.fn.pagination = function(maxentries, opts) {

 

      // Initialize options with default values

      opts = $.extend( {

         items_per_page : 1,

         num_display_entries : 4,

         current_page : 0,

         num_edge_entries : 1,

         link_to : "#",

         prev_text : "<i></i>上一页",

         next_text : "下一页 <i></i>",

         ellipse_text : "...",

         prev_show_always : true,

         next_show_always : true,

         renderer : "defaultRenderer",

         show_if_single_page : false,

         load_first_page : false,

         callback : function() {

            return false;

         }

      }, opts || {});

 

      var containers = this, renderer, links, current_page;

 

      // goto

      $(".page-btn").one("click", function() {

         var allPage = $(".allPage").text();

         // console.log(allPage);

            var goPage = $(".page-go input").val() - 1; // 跳转页数

            if (goPage > -1 && goPage < allPage) {

                opts.current_page = goPage;

                $("#Pagination").pagination(allPage, opts);

            } else {

                $("#Pagination").pagination(allPage);

            }

            // 清空用户跳转页数

            $(".page-go input").val("");

         });

 

      /**

       * This is the event handling function for the pagination links.

       *

       * @param {int}

       *            page_id The new page number

       */

      function paginationClickHandler(evt) {

         var links, new_current_page = $(evt.target).data('page_id'), continuePropagation = selectPage(new_current_page);

         if (!continuePropagation) {

            evt.stopPropagation();

         }

         return continuePropagation;

      }

 

      /**

       * This is a utility function for the internal event handlers. It sets

       * the new current page on the pagination container objects, generates a

       * new HTMl fragment for the pagination links and calls the callback

       * function.

       */

      function selectPage(new_current_page) {

         // update the link display of a all containers

         containers.data('current_page', new_current_page);

         links = renderer.getLinks(new_current_page, paginationClickHandler);

         containers.empty();

         links.appendTo(containers);

         // call the callback and propagate the event if it does not return

         // false

         var continuePropagation = opts.callback(new_current_page,

                containers);

         return continuePropagation;

      }

 

      // -----------------------------------

      // Initialize containers

      // -----------------------------------

      current_page = parseInt(opts.current_page);

      containers.data('current_page', current_page);

      // Create a sane value for maxentries and items_per_page

      maxentries = (!maxentries || maxentries < 0) ? 1 : maxentries;

      opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0) ? 1

            : opts.items_per_page;

 

      if (!$.PaginationRenderers[opts.renderer]) {

         throw new ReferenceError("Pagination renderer '" + opts.renderer

                + "' was not found in jQuery.PaginationRenderers object.");

      }

      renderer = new $.PaginationRenderers[opts.renderer](maxentries, opts);

 

      // Attach control events to the DOM elements

      var pc = new $.PaginationCalculator(maxentries, opts);

      var np = pc.numPages();

      containers.bind('setPage', {

         numPages : np

      }, function(evt, page_id) {

         if (page_id >= 0 && page_id < evt.data.numPages) {

            selectPage(page_id);

            return false;

         }

      });

      containers.bind('prevPage', function(evt) {

         var current_page = $(this).data('current_page');

         if (current_page > 0) {

            selectPage(current_page - 1);

         }

         return false;

      });

      containers.bind('nextPage', {

         numPages : np

      }, function(evt) {

         var current_page = $(this).data('current_page');

         if (current_page < evt.data.numPages - 1) {

            selectPage(current_page + 1);

         }

         return false;

      });

 

      // When all initialisation is done, draw the links

      links = renderer.getLinks(current_page, paginationClickHandler);

      containers.empty();

      if (np > 1 || opts.show_if_single_page) {

         links.appendTo(containers);

      }

      // call callback function

      if (opts.load_first_page) {

         opts.callback(current_page, containers);

      }

   } // End of $.fn.pagination block

 

})(jQuery);

 

 

目录
相关文章
|
7月前
|
SQL Java 关系型数据库
若依框架---PageHelper分页(十一)
若依框架---PageHelper分页(十一)
215 0
|
7月前
|
SQL Java 关系型数据库
PageHelper分页插件最新源码解读及使用
PageHelper分页插件最新源码解读及使用
|
7月前
配置乐观锁和分页插件
配置乐观锁和分页插件
31 0
|
SQL Java 数据库连接
Mybatis 是如何进行分页的,分页插件的原理是什么?
Mybatis 是如何进行分页的,分页插件的原理是什么?
159 0
|
SQL Oracle 关系型数据库
什么是分页?如何使用分页?(一)
什么是分页?如何使用分页?
184 0
|
7月前
|
前端开发
若依框架---分页功能
若依框架---分页功能
500 0
|
7月前
|
SQL 安全 Java
若依框架---PageHelper分页(十四)
若依框架---PageHelper分页(十四)
137 0
|
7月前
|
缓存 Java 关系型数据库
若依框架---PageHelper分页(十二)
若依框架---PageHelper分页(十二)
55 0
|
7月前
|
SQL 存储
若依框架---PageHelper分页(十五)
若依框架---PageHelper分页(十五)
212 0
|
SQL 存储 关系型数据库
什么是分页?如何使用分页?(二)
什么是分页?如何使用分页?
77 0