分页组件

某日,在公司写一个简单的活动页面,活动见链接 ,这个页面业务叫简单,核心就是一个分页内容,活动很快就搞定了,然后呢,就整理分页功能,写成一个插件。

  嗯~~~说弄就弄。

  首先呢,先将页面分成两个区域:内容展示区和控件按钮(分页,上下页,跳转页等)展示区

<div class="page-wrapper">
  <div class="page-content">
    内容区域
  </div>
  <div class="control-wrapper">
    分页按钮区域
  </div>
</div>

  页面结构是弄好了,那么下面就要开始写JS了。

  之前呢,公司也有类似的分页功能的功能函数,其采用的做法是:

    1. 请求接口获取所有的数据

    2. 将所有数据分页渲染到几个div中,类似的方式

    3. 然后用 tab 页的形式,控制 div 显示隐藏 

  这样的话,如果数据比较少还是ok的,但如果数据比较多的话,会出现几个问题,

    1. 接口请求时间问题

    2. 数据渲染时间问题(采用的 dom 渲染方式,这样页面需要较长的时间才能加载显示出来,用户体验就很差)

  

解决办法呢?

  一、接口改成分页请求

    1.  前端负责写一个模板页面,然后将分页模板交给后端;前端只需负责分页按钮的状态,给按钮加链接即可。(整个页面会刷新)

    2.  后端把总页数给前端,前端根据页码请求不同页面的内容

  二、优化渲染时间

    1. 把接口所有的数据请求出来

    2. 将所有数据分页,保存在一个对象中,如: { page: 1, content: .... }

    3. 分页渲染各个页面的内容

在听到大佬的指点后,感觉自己的代码还是有问题的,故分享下思路和整体代码。后续优化完后,在对文章修改

1、根据请求的数据,对数据进行分页保存。

2、根据需求,在分页控制器内添加相应的html。

3、渲染分页按钮和内容。

当前完整代码如下。

var Paganation = function (el, options) {
        /*
         * baseUrl          string      跳转链接(*)
         * curPage          number      当前页(*) 从1开始
         * totalPage        number      总页数(*)
         * arrow            boolean     是否有上下页
         * showLen          number      显示的按钮个数
         * pageDetail       boolean     是否显示具体的页码
         * isTail           boolean     首尾页
         * isShowInfo       boolean     是否显示页数详情
         * ellipsisClass    string      省略号类名
         * prefix           string      按钮类名前缀
         */

        this.el = el;
        let baseOptions = Object.assign({
            baseUrl: null,
            curPage: 1,
            totalPage: 100,
            isArrow: true,
            showNum: 10,
            prefix: 'page-',
            disabledClass: 'page-disabled',
            isTail: true,
            pageDetail: true,
            isShowInfo: true,
            ellipsisClass: ''
        }, options);

        /*
         * prev     string      上一页
         * next     string      下一页
         * start    string      首页
         * end      string      尾页
         * page     strign      具体的页码
         * info     string      页码详情
         */
        this.prevHTML = '';
        this.nextHTML = '';
        this.startHTML = '';
        this.endHTML = '';
        this.pageHTML = '';
        this.infoHTML = '';

        this._init(baseOptions);
    };

    Paganation.prototype = {

        constructor: Paganation,

        _analysisOptions: function (options) {
            for (let k in options) {
                this[k] = options[k];
            }
        },

        _init: function (options) {
            this._analysisOptions(options);

            if (!this.baseUrl) {
                throw new Error(`must set baseUrl`);
            }

            if (!this.el) {
                throw new Error(`must set a page container`);
            };

            this._render();
        },

        // set html
        _create: function () {
            this.curPage = +this.curPage;
            this.totalPage = +this.totalPage;
            if (this.curPage < 1) this.curPage = 1;
            if (this.curPage > this.totalPage) this.curPage = this.totalPage;
            if (this.isArrow) this._createArrow();
            if (this.isTail) this._createTail();
            if (this.isShowInfo) this._createInfo();
            if (this.pageDetail) this._createPage();
        },

        // 上下页
        _createArrow: function () {
            const disabledClass = this.disabledClass;
            const prevUrl = this.curPage == 1 ? 'javascript:void(0);' : this.baseUrl + (this.curPage - 1);
            const nextUrl = this.curPage == this.totalPage ? 'javascript:void(0);' : this.baseUrl + (+this.curPage + 1);
            const prevDisabled = this.curPage == 1 ? disabledClass : '';
            const nextDisabled = this.curPage == this.totalPage ? disabledClass : '';

            this.prevHTML = '<a class="' + this.prefix + 'item ' + prevDisabled + '" href="' + prevUrl + '">上一页</a>';
            this.nextHTML = '<a class="' + this.prefix + 'item ' + nextDisabled + '" href="' + nextUrl + '">下一页</a>';
        },

        // 首尾页
        _createTail: function () {
            const disabledClass = this.disabledClass;
            const startUrl = this.curPage == 1 ? 'javascript:void(0);' : this.baseUrl + 1;
            const endUrl = this.curPage == this.totalPage ? 'javascript:void(0);' : this.baseUrl + this.totalPage;
            const startDisabled = this.curPage == 1 ? disabledClass : '';
            const endDisabled = this.curPage == this.totalPage ? disabledClass : '';
            this.startHTML = '<a class="' + this.prefix + 'item ' + startDisabled + '" href="' + startUrl + '">首页</a>';
            this.endHTML = '<a class="' + this.prefix + 'item ' + endDisabled + '" href="' + endUrl + '">尾页</a>';
        },

        // 页数详情
        _createInfo: function () {
            this.infoHTML = '<span class="' + this.prefix + 'total">共<i>' + this.totalPage + '</i>页</span><span class="' + this.prefix + 'cur">当前第<i>' + this.curPage + '</i>页</span>'
        },

        // 具体的页码
        _createPage: function () {
            let str = '';
            let self = this;
            let showNum = this.showNum;
            let totalPage = this.totalPage;
            let curPage = this.curPage;
            const prefix = this.prefix;
            const centerStr = '<span class="' + this.ellipsisClass + '">...</span>';

            let urlFn = function (i) {
                return self.baseUrl + i;
            };
            let htmlStr = function (i) {
                const endabled = self.curPage == i ? self.disabledClass : '';
                return '<a class="' + prefix + 'item ' + endabled + '" href="' + urlFn(i) + '">' + i + '</a>';
            };

            if (showNum >= totalPage) {
                for (let i = 1; i <= totalPage; i++) {
                    str += htmlStr(i)
                }
            } else {
                if (curPage < totalPage - showNum + 1) { //头部
                    for (let i = 0; i < showNum - 1; i++) {
                        str += htmlStr(+curPage + i);
                    }
                    str += centerStr + htmlStr(totalPage);
                } else { // 尾部
                    for (let i = 1; i <= showNum; i++) {
                        str += htmlStr(totalPage - showNum + i);
                    }
                }
            }

            this.pageHTML = str;
        },

        _goPage: function (i) {
            this.curPage = i;
            this._render();
        },

        _render: function () {
            this._create();
            this.el.innerHTML = this.infoHTML + this.startHTML + this.prevHTML + this.pageHTML + this.nextHTML + this.endHTML;
        }
    }

  

  

posted @ 2018-05-24 17:55  莫问、前程  阅读(366)  评论(0编辑  收藏  举报