分页组件
某日,在公司写一个简单的活动页面,活动见链接 ,这个页面业务叫简单,核心就是一个分页内容,活动很快就搞定了,然后呢,就整理分页功能,写成一个插件。
嗯~~~说弄就弄。
首先呢,先将页面分成两个区域:内容展示区和控件按钮(分页,上下页,跳转页等)展示区
<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;
}
}

浙公网安备 33010602011771号