分享一個純JS編寫的分頁工具


> 最近在閱讀公司項目代碼的時候, 發(fā)現(xiàn)分頁部分看不懂了, 當(dāng)時我就想

>

> 最近在工作中遇到一些分頁相關(guān)的問題, 對于別人封裝好的又不咋會用, 于是 , 就突發(fā)奇想, 想寫一個屬于自己專屬的分頁工具, 滿足一下需求:

>

> * 用純js編寫

> * ?無依賴, 方便嵌入項目

>

> * ?最好能用到面向?qū)ο蟮闹R

>

> 綜上想法, 于是, 一個使用面向?qū)ο笏枷刖帉懙募僺分頁就出現(xiàn)了

>

> 如果有想用的朋友可以拿去用, 記得多多留下寶貴意見, 感激不盡, 對了 ,代碼是純js編寫. 使用到了es6語法,所以 不支持試es6語法的瀏覽器理論應(yīng)該跑不起來

## 工具源碼

```js

/**

?* 分頁參數(shù)配置對象,用于配置分頁參數(shù)信息

?*/

?class AttrConf{

? ? /**

? ? ?* 分頁基本屬性

? ? ?*/

? ? curPage = 1;

? ? limit = 10;

? ? limits = [10,20,30,50,100];

? ? dataTotal = 0;

? ? pageTotal = 0;

? ? pageBox = {

? ? ? ? items:7,

? ? ? ? pages:[],

? ? }

? ? rowNo = {

? ? ? ? start:1,

? ? ? ? end:1

? ? }

? ? /**

? ? ?* 分頁配置構(gòu)造器

? ? ?* @param {*} curPage 當(dāng)前頁

? ? ?* @param {*} limit 每頁顯示條數(shù)

? ? ?* @param {*} dataTotal 總數(shù)據(jù)條數(shù)

? ? ?*/

? ? constructor(curPage,limit,dataTotal){

? ? ? ? this.init({curPage,limit,dataTotal});

? ? }

? ? init(param){

? ? ? ? if(param.curPage){

? ? ? ? ? ? this.setCurPage(param.curPage);

? ? ? ? }

? ? ? ? if(param.limit){

? ? ? ? ? ? this.setLimit(param.limit);

? ? ? ? }

? ? ? ? if(param.dataTotal){

? ? ? ? ? ? this.setDataTotal(param.dataTotal);

? ? ? ? }

? ? ? ? this.initOthers();

? ? }

? ? /**

? ? ?* 初始化分頁配置項其他屬性

? ? ?*/

? ? initOthers(){

? ? ? ? //初始化總頁數(shù)

? ? ? ? if(this.dataTotal>0){

? ? ? ? ? ? this.pageTotal = parseInt(this.dataTotal / this.limit) + (this.dataTotal % this.limit == 0 ? 0 : 1);

? ? ? ? ? ? //確保當(dāng)前頁始終在總頁數(shù)限制范圍內(nèi)

? ? ? ? ? ? if(this.curPage > this.pageTotal){

? ? ? ? ? ? ? ? this.curPage = this.pageTotal;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //初始化當(dāng)前頁顯示數(shù)據(jù)索引

? ? ? ? if(this.dataTotal <= this.limit){

? ? ? ? ? ? this.rowNo.start = 1;

? ? ? ? ? ? this.rowNo.end = this.dataTotal;

? ? ? ? }else if(this.curPage == this.pageTotal){

? ? ? ? ? ? this.rowNo.start = (this.curPage - 1) * this.limit + 1;

? ? ? ? ? ? this.rowNo.end = this.dataTotal;

? ? ? ? }else{

? ? ? ? ? ? this.rowNo.start = (this.curPage - 1) * this.limit + 1;

? ? ? ? ? ? this.rowNo.end = this.rowNo.start + this.limit - 1;

? ? ? ? }

? ? ? ? //初始化頁碼總數(shù)

? ? ? ? this.setPageCodes();

? ? }

? ? /**

? ? ?* 設(shè)置當(dāng)前頁

? ? ?* @param {Number} curPage 當(dāng)前頁

? ? ?* @param {Boolean} reloadOthers 是否初始化其他屬性 默認(rèn)不初始化

? ? ?*/

? ? setCurPage(curPage,reloadOthers){

? ? ? ? this.curPage = curPage;

? ? ? ? if(reloadOthers == true){

? ? ? ? ? ? this.initOthers();

? ? ? ? }

? ? }

? ? /**

? ? ?* 設(shè)置每頁顯示條數(shù)

? ? ?* @param {Number} limit ?每頁條數(shù)

? ? ?* @param {Boolean} reloadOthers 是否初始化其他屬性 默認(rèn)不初始化

? ? ?*/

? ? setLimit(limit,reloadOthers){

? ? ? ? this.limit = limit;

? ? ? ? if(reloadOthers == true){

? ? ? ? ? ? this.initOthers();

? ? ? ? }

? ? }


? ? /**

? ? ?* 設(shè)置總數(shù)據(jù)條數(shù)

? ? ?* @param {Number} dataTotal ?總數(shù)據(jù)條數(shù)

? ? ?* @param {Boolean} reloadOthers 是否初始化其他屬性 默認(rèn)不初始化

? ? ?*/

? ? ?setDataTotal(dataTotal,reloadOthers){

? ? ? ? this.dataTotal = dataTotal;

? ? ? ? if(reloadOthers == true){

? ? ? ? ? ? this.initOthers();

? ? ? ? }

? ? }

? ? /**

? ? ?* 設(shè)置當(dāng)前頁顯示的可快捷跳轉(zhuǎn)的頁碼個數(shù) 如 2,3,4,5,6

? ? ?*/

? ? setPageCodes(){

? ? ? ? this.pageBox.pages = [];

? ? ? ? if(this.pageTotal <= this.pageBox.items){

? ? ? ? ? ? for(let i = 1; i <= this.pageTotal; i++){

? ? ? ? ? ? ? ? this.pageBox.pages.push(i);

? ? ? ? ? ? }

? ? ? ? ? ? return ;

? ? ? ? }

? ? ? ? //總頁數(shù)大于配置的要顯示的總頁碼數(shù), 比如 總頁數(shù)是10 ,配置的是每頁顯示6個頁碼

? ? ? ? //得到以當(dāng)前頁為中心向左右便宜的偏移量 向下取整

? ? ? ? let offset = Math.floor(this.pageBox.items / 2);

? ? ? ? this.pageBox.pages.push(this.curPage);

? ? ? ? let pagesLen = this.pageBox.pages.length;

? ? ? ? let skipL = 0,skipR = 0;

? ? ? ? for(let i = 1; i <= offset; i++){

? ? ? ? ? ? let maxPage = this.curPage + i;

? ? ? ? ? ? let minPage = this.curPage - i;

? ? ? ? ? ? //每循環(huán)一次,檢測一次當(dāng)前總頁碼項數(shù),只有總頁碼項數(shù)小于配置項才添加

? ? ? ? ? ? if(pagesLen < this.pageBox.items){

? ? ? ? ? ? ? ? //往右邊添加頁碼

? ? ? ? ? ? ? ? if(minPage >= 1){

? ? ? ? ? ? ? ? ? ? this.pageBox.pages.unshift(minPage);

? ? ? ? ? ? ? ? ? ? //從新計算總頁碼相熟 方便下次循環(huán)參考

? ? ? ? ? ? ? ? ? ? pagesLen += 1;

? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? skipR += 1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }


? ? ? ? ? ? if(pagesLen < this.pageBox.items){

? ? ? ? ? ? ? ? //往左邊添加頁碼

? ? ? ? ? ? ? ? if(maxPage <= this.pageTotal){

? ? ? ? ? ? ? ? ? ? this.pageBox.pages.push(maxPage);

? ? ? ? ? ? ? ? ? ? //從新計算總頁碼相熟 方便下次循環(huán)參考

? ? ? ? ? ? ? ? ? ? pagesLen += 1;

? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? skipL += 1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //處理總頁碼數(shù)不滿足配置項的情況

? ? ? ? if(skipL > 0 ){

? ? ? ? ? ? //說明需要向左邊補充skipL個盒子

? ? ? ? ? ? for(let i = 1; i <= skipL; i++){

? ? ? ? ? ? ? ? let startPage = this.pageBox.pages[0];

? ? ? ? ? ? ? ? if(pagesLen < this.pageBox.items){

? ? ? ? ? ? ? ? ? ? this.pageBox.pages.unshift(startPage - 1);

? ? ? ? ? ? ? ? ? ? //從新計算總頁碼相熟 方便下次循環(huán)參考

? ? ? ? ? ? ? ? ? ? pagesLen += 1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? if(skipR > 0 ){

? ? ? ? ? ? //說明需要向左邊補充skipL個盒子

? ? ? ? ? ? for(let i = 1; i <= skipR; i++){

? ? ? ? ? ? ? ? let endPage = this.pageBox.pages[pagesLen-1];

? ? ? ? ? ? ? ? if(pagesLen < this.pageBox.items){

? ? ? ? ? ? ? ? ? ? this.pageBox.pages.push(endPage + 1);

? ? ? ? ? ? ? ? ? ? //從新計算總頁碼相熟 方便下次循環(huán)參考

? ? ? ? ? ? ? ? ? ? pagesLen += 1;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

/**

?* 分頁視圖配置對象,用于根據(jù)分頁參數(shù)創(chuàng)建dom元素

?*/

class ViewConf{

? ? AttrConf;

? ? /**

? ? ?* 分頁視圖對象 分為左右兩大區(qū)域,當(dāng)左側(cè)隱藏,右側(cè)自動填充

? ? ?* ? 左側(cè)區(qū)域 可以顯示或關(guān)閉

? ? ?* ? ? ?基本信息(base)

? ? ?* ? 右側(cè)區(qū)域 以下視圖模塊可任意組合

? ? ?* ? ? ?上一頁(prev),下一頁(next),頁碼區(qū)(pages),每頁顯示條數(shù)(limits),快速跳轉(zhuǎn)(jump)

? ? ?*/

? ? layout = {

? ? ? ? unit: '%',

? ? ? ? main: null,

? ? ? ? left:{

? ? ? ? ? ? show: true,

? ? ? ? ? ? width: 27,

? ? ? ? ? ? ids: ['base'],

? ? ? ? ? ? dom:null,

? ? ? ? ? ? modules: {},

? ? ? ? },

? ? ? ? right:{

? ? ? ? ? ? width: 100,

? ? ? ? ? ? ids: ['prev','pages','next','limits','jump'],

? ? ? ? ? ? dom:null,

? ? ? ? ? ? modules:{}

? ? ? ? }

? ? };

? ? modules = {

? ? ? ? pages:[]

? ? };

? ? // 分頁按鈕顏色主題配置

? ? theme = {

? ? ? ? deault:{

? ? ? ? ? ? pageBtn:{border:"#e1f5fe",boxShadow:"#c4d8e0"},

? ? ? ? ? ? pageBtnCur:{border:"#e1f5fe",color:"#8BC34A",boxShadow:"#c4d8e0",backgroundColor:"#e1f5fe"},

? ? ? ? ? ? pageBtnDisabled:{border:"#e1f5fe",color:"#636262",boxShadow:"#ddf2fb"},

? ? ? ? }

? ? }

? ? //默認(rèn) 基本樣式

? ? cssMap = {

? ? ? ? base:{//分頁信息樣式

? ? ? ? ? ? fontSize: ?"13px",

? ? ? ? ? ? color: ?"rgb(58, 63, 66)",

? ? ? ? },

? ? ? ? pageBtn:{ //按鈕基本樣式

? ? ? ? ? ? border: ?"1px solid #ccc",

? ? ? ? ? ? padding: ?"3px 5px",

? ? ? ? ? ? borderRadius: ?"3px",

? ? ? ? ? ? display: ?"inline-block",

? ? ? ? ? ? fontSize: ?"13px",

? ? ? ? ? ? margin: ?"0 2px",

? ? ? ? ? ? boxShadow: ?"inset 0px 0px 3px 1px #c7c2c2",

? ? ? ? ? ? height: ?"20px",

? ? ? ? ? ? color: ?"rgb(58, 63, 66)",

? ? ? ? ? ? lineHeight: ?"20px",

? ? ? ? ? ? minWidth: ?"30px",

? ? ? ? ? ? textAlign: ?"center",

? ? ? ? ? ? cursor: ?"pointer",

? ? ? ? ? ? textDecoration: "unset"

? ? ? ? },

? ? ? ? pageBtnHover:{//鼠標(biāo)經(jīng)過按鈕樣式

? ? ? ? ? ? boxShadow: "inset 0px 0px 4px 2px #c7c2c2",

? ? ? ? ? ? color:"unset"

? ? ? ? },

? ? ? ? pageBtnPressDown:{//按鈕按下樣式

? ? ? ? ? ? color:"darkorange",

? ? ? ? ? ? boxShadow: "inset 0px 0px 5px 3px #c7c2c2",

? ? ? ? ? ? fontWeight: "bolder",

? ? ? ? },

? ? ? ? pageBtnCur:{ //當(dāng)前頁按鈕樣式

? ? ? ? ? ? boxShadow: "#81D4FA 0px 0px 3px 1px inset",

? ? ? ? ? ? color:"#009688",

? ? ? ? ? ? fontWeight: "bolder",

? ? ? ? ? ? cursor: "not-allowed",

? ? ? ? ? ? border: "1px solid #E1F5FE",

? ? ? ? ? ? backgroundColor:"#E1F5FE"

? ? ? ? },

? ? ? ? pageBtnDisabled:{//按鈕禁用樣式

? ? ? ? ? ? border: "1px solid #efefef",

? ? ? ? ? ? boxShadow: "#efefef 0px 0px 3px 1px inset",

? ? ? ? ? ? color: "#efefef",

? ? ? ? ? ? cursor: "not-allowed",

? ? ? ? }

? ? }

? ? /**

? ? ?* 分頁視圖對象構(gòu)造器

? ? ?* @param {AttrConf} AttrConf 對象

? ? ?*/

? ? constructor(AttrConf,theme){

? ? ? ? this.AttrConf = AttrConf;


? ? ? ? this.initTheme(theme);

? ? ? ? this.initLayout();

? ? ? ? this.initModuls();

? ? }

? ? /**

? ? ?* 設(shè)置主題樣式

? ? ?* @param {*} theme

? ? ?*/

? ? initTheme(theme){

? ? ? ? if(!theme)

? ? ? ? ? ? theme = "default";

? ? ? ? let themeConf = this.theme[theme];

? ? ? ? if(!themeConf)

? ? ? ? ? ? themeConf = this.theme.deault;

? ? ? ? for(let key in this.cssMap){

? ? ? ? ? ? switch(key){

? ? ? ? ? ? ? ? case "pageBtn":

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtn.border = "1px solid " + themeConf.pageBtn.border;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtn.boxShadow = "inset 0px 0px 3px 1px " + themeConf.pageBtn.boxShadow;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnHover.boxShadow = "inset 0px 0px 5px 1px " + themeConf.pageBtn.boxShadow;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnPressDown.boxShadow = "inset 0px 0px 7px 2px " + themeConf.pageBtn.boxShadow;

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? case "pageBtnCur":

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnCur.border = "1px solid " + themeConf.pageBtnCur.border;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnCur.boxShadow = "inset 0px 0px 3px 1px " + themeConf.pageBtnCur.boxShadow;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnCur.color = themeConf.pageBtnCur.color;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnCur.backgroundColor = themeConf.pageBtnCur.backgroundColor;

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? case "pageBtnDisabled":

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnDisabled.border = "1px solid " + themeConf.pageBtnDisabled.border;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnDisabled.boxShadow = "inset 0px 0px 3px 1px " + themeConf.pageBtnDisabled.boxShadow;

? ? ? ? ? ? ? ? ? ? this.cssMap.pageBtnDisabled.color = themeConf.pageBtnDisabled.color;

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? }


? ? /**

? ? ?* 初始化視圖布局

? ? ?*/

? ? initLayout(){

? ? ? ? this.layout.main = this.createElem('div',{layout:'main'},null);

? ? ? ? //重置右布局寬度

? ? ? ? let ids = null;

? ? ? ? let inst = this;

? ? ? ? if(inst.layout.left.show){

? ? ? ? ? ? inst.layout.right.width =- ?inst.layout.left.width;

? ? ? ? ? ? //創(chuàng)建左布局容器

? ? ? ? ? ? inst.layout.left.dom

? ? ? ? ? ? ? ? = inst.createElem('div',{layout:'left'},{width: inst.layout.left.width+inst.layout.unit});

? ? ? ? ? ? //添加模塊

? ? ? ? ? ? ids = inst.layout.left.ids;

? ? ? ? ? ? ids.forEach(domId => inst.layout.left.modules[domId]

? ? ? ? ? ? ? ? = inst.createElem('div',{module:domId},{}));

? ? ? ? }

? ? ? ? //創(chuàng)建右布局容器

? ? ? ? inst.layout.right.dom

? ? ? ? ? ? ? ? = inst.createElem('div',{layout:'right'},{width: inst.layout.right.width+inst.layout.unit});

? ? ? ? //添加模塊

? ? ? ? ids = inst.layout.right.ids;

? ? ? ? ids.forEach(domId => inst.layout.right.modules[domId]

? ? ? ? ? ? = inst.createElem('span',{module:domId},{}));

? ? }

? ? setLayout(layout){

? ? ? ? if(layout.left){

? ? ? ? ? ? if(layout.left.show){

? ? ? ? ? ? ? ? this.layout.left.show = layout.left.show;

? ? ? ? ? ? }

? ? ? ? ? ? if(layout.left.modules){

? ? ? ? ? ? ? ? this.layout.left.ids = layout.left.modules;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? if(layout.right){

? ? ? ? ? ? if(layout.right.modules){

? ? ? ? ? ? ? ? this.layout.right.ids = layout.right.modules;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? this.initLayout();

? ? ? ? this.initModuls();

? ? }

? ? /**

? ? ?* 初始化模型,根據(jù)視圖下的模型個數(shù)確定

? ? ?*/

? ? initModuls(){


? ? ? ? let modules = [];

? ? ? ? let inst = this;

? ? ? ? if(this.layout.left.show){

? ? ? ? ? ? this.layout.left.ids.forEach(mode => modules.push(mode));

? ? ? ? }

? ? ? ? this.layout.right.ids.forEach(mode => modules.push(mode));

? ? ? ? modules.forEach(module => {

? ? ? ? ? ? let fnName = 'load' + module.substring(0,1).toUpperCase() + module.substring(1);

? ? ? ? ? ? try{

? ? ? ? ? ? ? ? inst[fnName](true);

? ? ? ? ? ? }catch(e){

? ? ? ? ? ? ? ? console.warn("模塊錯誤,未知的模塊名:"+module)

? ? ? ? ? ? }

? ? ? ? })

? ? }

? ? loadBase(){

? ? ? ? if(!this.modules.base){

? ? ? ? ? ? let baseDom = this.createElem('div',{module:"base"});

? ? ? ? ? ? baseDom.innerHTML = `

? ? ? ? ? ? ? ? <div>

? ? ? ? ? ? ? ? ? ? <small>當(dāng)前顯示第 <b><start>`+this.AttrConf.rowNo.start+`</start><i>~</i><end>`+this.AttrConf.rowNo.end+`</end></b> 條</small>

? ? ? ? ? ? ? ? </div>

? ? ? ? ? ? ? ? <div>

? ? ? ? ? ? ? ? ? ? <small>第 <b><cur-page>`+this.AttrConf.curPage+`</cur-page><i>/</i><total-page>`+this.AttrConf.pageTotal+`</total-page></b> 頁</small>

? ? ? ? ? ? ? ? ? ? <small>共 <b><total-data>`+this.AttrConf.dataTotal+`</total-data></b> 條記錄</small> ?

? ? ? ? ? ? ? ? </div>`;

? ? ? ? ? ? this.modules.base = baseDom;

? ? ? ? }

? ? ? ? let baseDom = this.modules.base;

? ? ? ? baseDom.querySelector("start").innerHTML = this.AttrConf.rowNo.start;

? ? ? ? baseDom.querySelector("end").innerHTML = this.AttrConf.rowNo.end;

? ? ? ? baseDom.querySelector("cur-page").innerHTML = this.AttrConf.curPage;

? ? ? ? baseDom.querySelector("total-page").innerHTML = this.AttrConf.pageTotal;

? ? ? ? baseDom.querySelector("total-data").innerHTML = this.AttrConf.dataTotal;

? ? }

? ? /**

? ? ?* 加載分頁頁碼

? ? ?*/

? ? loadPages(isInit){

? ? ? ? if(isInit == true){

? ? ? ? ? ? //初始化

? ? ? ? ? ? this.modules.pages = [];

? ? ? ? ? ? for(let i = 0;i < this.AttrConf.pageBox.pages.length; i++){

? ? ? ? ? ? ? ? this.modules.pages.push(this.createElem('a',{href:"#",btn:"code",module:"pages"},this.cssMap.pageBtn));

? ? ? ? ? ? }


? ? ? ? }

? ? ? ? //修改屬性

? ? ? ? for(let i = 0;i < this.AttrConf.pageBox.items; i++){

? ? ? ? ? ? let code = this.AttrConf.pageBox.pages[i];

? ? ? ? ? ? let page = this.modules.pages[i];

? ? ? ? ? ? page.innerHTML = code;


? ? ? ? ? ? let attrMap = {

? ? ? ? ? ? ? ? pagecode: code,

? ? ? ? ? ? };

? ? ? ? ? ? if(code == this.AttrConf.curPage){

? ? ? ? ? ? ? ? attrMap.active = "";

? ? ? ? ? ? ? ? attrMap.disabled = "";

? ? ? ? ? ? }

? ? ? ? ? ? this.attr(page,attrMap);

? ? ? ? }

? ? ? ? let offset = Math.floor(this.AttrConf.pageBox.items / 2);


? ? ? ? if((this.AttrConf.curPage - offset) > 1){

? ? ? ? ? ? let first = this.createElemBase('a',1);

? ? ? ? ? ? this.attr(first,{

? ? ? ? ? ? ? ? pagecode: 1,

? ? ? ? ? ? ? ? href:"#",

? ? ? ? ? ? ? ? btn:"code"

? ? ? ? ? ? });

? ? ? ? ? ? let lblL = this.createElemBase('a','...');

? ? ? ? ? ? this.attr(lblL,{

? ? ? ? ? ? ? ? disabled : "",

? ? ? ? ? ? ? ? href:"#",

? ? ? ? ? ? ? ? btn:""

? ? ? ? ? ? });


? ? ? ? ? ? this.css(first,this.cssMap.pageBtn);

? ? ? ? ? ? this.css(lblL,this.cssMap.pageBtn);

? ? ? ? ? ? this.modules.pages.unshift(lblL);

? ? ? ? ? ? this.modules.pages.unshift(first);

? ? ? ? }

? ? ? ? if((this.AttrConf.curPage + offset) < this.AttrConf.pageTotal){

? ? ? ? ? ? let last = this.createElemBase('a',this.AttrConf.pageTotal);

? ? ? ? ? ? this.attr(last,{

? ? ? ? ? ? ? ? pagecode: this.AttrConf.pageTotal,

? ? ? ? ? ? ? ? href:"#",

? ? ? ? ? ? ? ? btn:"code"

? ? ? ? ? ? });

? ? ? ? ? ? let lblR = this.createElemBase('a','...');

? ? ? ? ? ? this.attr(lblR,{

? ? ? ? ? ? ? ? disabled : "",

? ? ? ? ? ? ? ? href:"#",

? ? ? ? ? ? ? ? btn:""

? ? ? ? ? ? });


? ? ? ? ? ? this.css(last,this.cssMap.pageBtn);

? ? ? ? ? ? this.css(lblR,this.cssMap.pageBtn);

? ? ? ? ? ? this.modules.pages.push(lblR);

? ? ? ? ? ? this.modules.pages.push(last);

? ? ? ? }

? ? }

? ? /**

? ? ?* 加載上一頁

? ? ?* @param {Boolean} isInit

? ? ?*/

? ? loadPrev(isInit){

? ? ? ? if(isInit){

? ? ? ? ? ? this.modules.prev = this.createElem('a',{href:"#",btn:"code",module:"prev"},this.cssMap.pageBtn,'上一頁');

? ? ? ? }

? ? ? ? // 設(shè)置按鈕狀態(tài)

? ? ? ? let attrMap = {

? ? ? ? ? ? pagecode: this.AttrConf.curPage - 1

? ? ? ? }

? ? ? ? if(this.AttrConf.curPage <= 1){

? ? ? ? ? ? attrMap.disabled = ""

? ? ? ? }

? ? ? ? this.attr(this.modules.prev,attrMap);

? ? }

? ? /**

? ? ?* 加載下一頁

? ? ?* @param {Boolean} isInit

? ? ?*/

? ? loadNext(isInit){

? ? ? ? if(isInit){

? ? ? ? ? ? this.modules.next = this.createElem('a',{href:"#",btn:"code",module:"next"},this.cssMap.pageBtn,'下一頁');

? ? ? ? }

? ? ? ? // 設(shè)置按鈕狀態(tài)

? ? ? ? let attrMap = {

? ? ? ? ? ? pagecode: this.AttrConf.curPage + 1

? ? ? ? }

? ? ? ? if(this.AttrConf.curPage >= this.AttrConf.pageTotal){

? ? ? ? ? ? attrMap.disabled = ""

? ? ? ? }

? ? ? ? this.attr(this.modules.next,attrMap);

? ? }

? ? /**

? ? ?* 加載快捷跳頁

? ? ?* @param {Boolean} isInit

? ? ?*/

? ? loadJump(isInit){

? ? ? ? if(isInit){

? ? ? ? ? ? let jump = this.createElem("span",{module:"jump"},this.cssMap.pageBtn,null);

? ? ? ? ? ? let jumpInput = this.createElem('input',{

? ? ? ? ? ? ? ? type: "text",

? ? ? ? ? ? ? ? maxlength: (this.AttrConf.pageTotal+"").length,

? ? ? ? ? ? ? ? value: this.AttrConf.curPage

? ? ? ? ? ? },{

? ? ? ? ? ? ? ? width: ((this.AttrConf.pageTotal+"").length * 11) + "px",

? ? ? ? ? ? ? ? textAlign: 'center',

? ? ? ? ? ? ? ? fontWeight: 'bolder',

? ? ? ? ? ? ? ? fontSize: '14px',

? ? ? ? ? ? ? ? border: "unset",

? ? ? ? ? ? },null);

? ? ? ? ? ? let jumpGo = this.createElem("a",{href:"#"},{},'Go');

? ? ? ? ? ? jump.appendChild(this.createElemBase("span","到第"));

? ? ? ? ? ? jump.appendChild(jumpInput);

? ? ? ? ? ? jump.appendChild(this.createElemBase("span","<b>/ "+this.AttrConf.pageTotal+"</b>頁 "));

? ? ? ? ? ? jump.appendChild(jumpGo);

? ? ? ? ? ? this.modules.jump = jump;

? ? ? ? }

? ? }

? ? /**

? ? ?* 加載每頁顯示控制

? ? ?* @param {Boolean} isInit

? ? ?*/

? ? ?loadLimits(isInit){

? ? ? ? if(isInit){

? ? ? ? ? ? let limits = this.createElem("span",{module:"limits"},this.cssMap.pageBtn,null);

? ? ? ? ? ? let limitsSelect = this.createElem('select',{},{border:"unset"},null);

? ? ? ? ? ? for(let i in this.AttrConf.limits){

? ? ? ? ? ? ? ? let limit = this.AttrConf.limits[i];

? ? ? ? ? ? ? ? let attr = {

? ? ? ? ? ? ? ? ? ? value: limit

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if(this.AttrConf.limit == limit){

? ? ? ? ? ? ? ? ? ? attr.selected = true;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? limitsSelect.appendChild(this.createElem('option',attr,{},limit+"條/頁"));

? ? ? ? ? ? }

? ? ? ? ? ? limits.appendChild(limitsSelect);

? ? ? ? ? ? this.modules.limits = limits;

? ? ? ? }

? ? }

? ? attr(dom,attrMap){

? ? ? ? Object.keys(attrMap).forEach(attr => dom.setAttribute(attr,attrMap[attr]));

? ? }

? ? css(dom,cssMap){

? ? ? ? Object.keys(cssMap).forEach(css => dom.style[css] = cssMap[css]);

? ? }

? ? createElemBase(elemTag,elemName){

? ? ? ? let elem ?= ?document.createElement(elemTag);

? ? ? ? if(elemName){

? ? ? ? ? ? elem.innerHTML = elemName;

? ? ? ? }

? ? ? ? return elem;

? ? }

? ? createElem(elemTag,attrMap,cssMap,elemName){

? ? ? ? let elem = this.createElemBase(elemTag,elemName);

? ? ? ? if(attrMap){

? ? ? ? ? ? this.attr(elem,attrMap);

? ? ? ? }

? ? ? ? if(cssMap){

? ? ? ? ? ? this.css(elem,cssMap);

? ? ? ? }

? ? ? ? return elem;

? ? }

}

/**

?* 分頁工具對象 負(fù)責(zé)和調(diào)用方打交道, 同時協(xié)調(diào)AttrConf,ViewConf的屬性和相關(guān)監(jiān)聽方法

?*/

class PageUtil{

? ? AttrConf;

? ? ViewConf;

? ? config = {

? ? ? ? layout: {

? ? ? ? ? ? left:{

? ? ? ? ? ? ? ? show: true,

? ? ? ? ? ? ? ? modules: ['base'],

? ? ? ? ? ? },

? ? ? ? ? ? right:{

? ? ? ? ? ? ? ? modules:[,'prev','pages','next','limits','jump'],

? ? ? ? ? ? }

? ? ? ? },

? ? ? ? action: {

? ? ? ? ? ? toPage(index,limit){

? ? ? ? ? ? ? ? //實際使用的使用可以通過該方法獲取到當(dāng)前分頁參數(shù)信息

? ? ? ? ? ? },

? ? ? ? ? ? error(info){

? ? ? ? ? ? ? ? console.log(info);

? ? ? ? ? ? }

? ? ? ? },

? ? };

? ? constructor(elem){

? ? ? ? this.elem = elem;

? ? ? ? if(typeof(elem) == "string"){

? ? ? ? ? ? this.elem = document.querySelector(elem);

? ? ? ? }

? ? }

? ? render(param){

? ? ? ? if(param){

? ? ? ? ? ? //首次使用的時候 需要先初始化 AttrConf對象

? ? ? ? ? ? this.AttrConf = param.AttrConf;

? ? ? ? ? ? this.ViewConf = new ViewConf(this.AttrConf);

? ? ? ? ? ? if(param.action){

? ? ? ? ? ? ? ? let action = param.action;

? ? ? ? ? ? ? ? if(action.toPage){

? ? ? ? ? ? ? ? ? ? this.config.action.toPage = action.toPage;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? /* 初始化布局配置 */

? ? ? ? ? ? if(param.layout){

? ? ? ? ? ? ? ? let layout = param.layout;

? ? ? ? ? ? ? ? if(layout.left){

? ? ? ? ? ? ? ? ? ? if(layout.left.show != undefined){

? ? ? ? ? ? ? ? ? ? ? ? this.config.layout.left.show = layout.left.show;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if(layout.left.modules){

? ? ? ? ? ? ? ? ? ? ? ? this.config.layout.left.modules = layout.left.modules;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if(layout.right){

? ? ? ? ? ? ? ? ? ? if(layout.right.modules){

? ? ? ? ? ? ? ? ? ? ? ? this.config.layout.left.modules = layout.left.modules;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? //從新渲染下布局

? ? ? ? ? ? ? ? this.ViewConf.setLayout(this.config.layout);

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? //從視圖配置中把視圖加載到頁面, 完成按鈕狀態(tài),事件的渲染

? ? ? ? this.loadPageViewToDom();

? ? ? ? this.renderPageBtnStyle();

? ? ? ? this.renderPageBtnAction();

? ? }

? ? loadPageViewToDom(){

? ? ? ? let inst = this;

? ? ? ? let layout = inst.config.layout;

? ? ? ? //初始化左容器視圖

? ? ? ? if(layout.left.show){

? ? ? ? ? ? inst.elem.appendChild(this.ViewConf.layout.left.dom);

? ? ? ? ? ? inst.ViewConf.layout.left.ids.forEach(modeName => {

? ? ? ? ? ? ? ? inst.elem.querySelector("[layout=left]").appendChild(inst.ViewConf.modules[modeName]);

? ? ? ? ? ? })

? ? ? ? }

? ? ? ? inst.elem.appendChild(this.ViewConf.layout.right.dom);

? ? ? ? inst.ViewConf.layout.right.ids.forEach(modeName => {

? ? ? ? ? ? if(modeName == 'pages'){

? ? ? ? ? ? ? ? for(let i in inst.ViewConf.modules.pages){

? ? ? ? ? ? ? ? ? ? let codeDom = inst.ViewConf.modules.pages[i];

? ? ? ? ? ? ? ? ? ? inst.elem.querySelector("[layout=right]").appendChild(codeDom);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? inst.elem.querySelector("[layout=right]").appendChild(inst.ViewConf.modules[modeName]);

? ? ? ? ? ? }

? ? ? ? })

? ? }

? ? /**

? ? ?* 渲染分頁按鈕狀態(tài)樣式

? ? ?*/

? ? renderPageBtnStyle(){

? ? ? ? let inst = this;

? ? ? ? //渲染按鈕 經(jīng)過 -- 按下 -- 離開樣式

? ? ? ? let pressDowCss = inst.ViewConf.cssMap.pageBtnPressDown;

? ? ? ? let hoverCss = inst.ViewConf.cssMap.pageBtnHover;

? ? ? ? let baseCss = inst.ViewConf.cssMap.pageBtn;

? ? ? ? this.elem.querySelectorAll('[btn]:not([active]):not([disabled])').forEach(dom => {

? ? ? ? ? ? dom.addEventListener('mouseenter',

? ? ? ? ? ? ? ? () => inst.ViewConf.css(dom,hoverCss));

? ? ? ? ? ? dom.addEventListener('mousedown',

? ? ? ? ? ? ? ? () => inst.ViewConf.css(dom,pressDowCss));

? ? ? ? ? ? dom.addEventListener('mouseup',

? ? ? ? ? ? ? ? () => inst.ViewConf.css(dom,hoverCss));

? ? ? ? ? ? dom.addEventListener('mouseleave',

? ? ? ? ? ? ? ? () => inst.ViewConf.css(dom,baseCss));

? ? ? ? });

? ? ? ? //渲染禁用按鈕樣式

? ? ? ? let disabledCss = inst.ViewConf.cssMap.pageBtnDisabled;

? ? ? ? this.elem.querySelectorAll('[disabled]:not([active])').forEach(dom => {

? ? ? ? ? ? inst.ViewConf.css(dom,disabledCss);

? ? ? ? });

? ? ? ? //渲染當(dāng)前選中按鈕樣式

? ? ? ? let activeCss = inst.ViewConf.cssMap.pageBtnCur;

? ? ? ? this.elem.querySelectorAll('[active]').forEach(dom => {

? ? ? ? ? ? inst.ViewConf.css(dom,activeCss);

? ? ? ? });

? ? ? ? if(inst.ViewConf.layout.left.show == true){

? ? ? ? ? ? let left = this.elem.querySelector('[layout=left]');

? ? ? ? ? ? inst.ViewConf.css(left,{

? ? ? ? ? ? ? ? display: 'table-cell'

? ? ? ? ? ? });

? ? ? ? ? ? left.setAttribute("algin","left");

? ? ? ? }

? ? ? ? let right = this.elem.querySelector('[layout=right]');

? ? ? ? inst.ViewConf.css(right,{

? ? ? ? ? ? display: 'table-cell',

? ? ? ? ? ? verticalAlign: 'middle',

? ? ? ? });

? ? ? ? right.setAttribute("align","right");

? ? ? ? this.ViewConf.css(this.elem,{

? ? ? ? ? ? display: "inline-table",

? ? ? ? ? ? width: "100%",

? ? ? ? });

? ? ? ? this.ViewConf.css(this.elem.querySelector("[module=base]"),this.ViewConf.cssMap.base);

? ? }

? ? /**

? ? ?* 渲染分頁按鈕事件

? ? ?*/

? ? renderPageBtnAction(){

? ? ? ? let inst = this;

? ? ? ? //頁碼 上一頁 下一頁事件

? ? ? ? inst.elem.querySelectorAll("[btn]:not([active]):not([disabled])")

? ? ? ? ? ? .forEach(dom => dom.addEventListener('click',toPage));


? ? ? ? function toPage(e){

? ? ? ? ? ? let curPage = this.getAttribute("pagecode");


? ? ? ? ? ? inst.toPage(parseInt(curPage));

? ? ? ? }

? ? ? ? //跳轉(zhuǎn)到指定頁事件

? ? ? ? inst.elem.querySelector("[module=jump]>input").addEventListener('blur',(e)=>{

? ? ? ? ? ? let val = parseInt(e.target.value);

? ? ? ? ? ? if(isNaN(val)){

? ? ? ? ? ? ? ? inst.config.action.error({module:'jump',ele:e.target,type:'頁碼轉(zhuǎn)換異常',msg:"頁碼錯誤,只能輸入數(shù)字,實際輸入值為:"+e.target.value});

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }

? ? ? ? ? ? val = val < 1 ? 1 : (val > inst.AttrConf.pageTotal ? inst.AttrConf.pageTotal : val);

? ? ? ? ? ? inst.toPage(val);

? ? ? ? });

? ? ? ? inst.elem.querySelector("[module=jump]>input").addEventListener('focus',(e)=>e.target.select());

? ? ? ? //每頁顯示配置事件

? ? ? ? inst.elem.querySelector("[module=limits]>select").addEventListener('change',(e)=>{

? ? ? ? ? ? let ele = e.target;

? ? ? ? ? ? let curIndex = ele.selectedIndex;

? ? ? ? ? ? let val = parseInt(ele.options[curIndex].value);

? ? ? ? ? ? inst.AttrConf.init({limit:val});

? ? ? ? ? ? inst.toPage(1);

? ? ? ? ? ? console.log(inst.AttrConf);

? ? ? ? });

? ? }

? ? /**

? ? ?* 跳轉(zhuǎn)到指定頁

? ? ?* @param {Number} pageCode

? ? ?*/

? ? toPage(pageCode){

? ? ? ? //設(shè)置新頁碼

? ? ? ? this.AttrConf.setCurPage(pageCode);

? ? ? ? //暴露給需要分頁對象的方法, 執(zhí)行后 會重新初始化總數(shù)據(jù)條數(shù)

? ? ? ? this.config.action.toPage(pageCode,this.AttrConf.limit);

? ? ? ? this.AttrConf.initOthers();

? ? ? ? //重新初始化視圖模型

? ? ? ? this.ViewConf.initModuls();

? ? ? ? //刪除之前的舊頁碼

? ? ? ? this.elem.querySelector("[layout=right]").innerHTML = "";


? ? ? ? this.render();

? ? }

}

```

## 如何使用

* 在html中引入js代碼

* 以下是可以直接運行的html演示代碼, 可以直接coyp, 注意引用就行

? ```

? <!DOCTYPE html>

? <html lang="en">

? <head>

? ? ? <meta charset="UTF-8">

? ? ? <meta http-equiv="X-UA-Compatible" content="IE=edge">

? ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? ? ? <title>Document</title>

? ? ? <script src="./page-utils-v2.js"></script>

? ? <style>

? ? ? ? .box{

? ? ? ? ? ? padding: 30px;

? ? ? ? ? ? width:80% !important;

? ? ? ? ? ? border: 1px solid #ccc;

? ? ? ? }

? ? </style>

? </head>

? <body>

? ? ? <div id="page" class="box"></div>

? ? ? <div id="page1"class="box"></div>

? ? ? <div id="page2"class="box"></div>

? ? ? <div id="page3"class="box"></div>

? ? ? <script>

? ? ? ? // 創(chuàng)建分頁對象, #page是需要放分頁的容器選擇器, 也可以是一個HTMLdom對象

? ? ? ? ? var pageUtil = new PageUtil("#page");

? ? ? ? ? var pageUtil1 = new PageUtil("#page1");

? ? ? ? ? var pageUtil2 = new PageUtil("#page2");

? ? ? ? ? var pageUtil3 = new PageUtil("#page3");


? ? ? ? // 第一次加載的時候,需要這樣寫

? ? ? ? ? pageUtil.render({

? ? ? ? ? ? ? AttrConf: new AttrConf(1,10,2020)

? ? ? ? ? });

? ? ? ? pageUtil1.render({

? ? ? ? ? ? ? AttrConf: new AttrConf(1,20,1668),

? ? ? ? ? ? layout: {

? ? ? ? ? ? ? ? left:{

? ? ? ? ? ? ? ? ? ? show: true,

? ? ? ? ? ? ? ? ? ? modules: ['base'],

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? right:{

? ? ? ? ? ? ? ? ? ? modules:['prev','pages','next','limits','jump'],

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? });

? ? ? ? pageUtil2.render({

? ? ? ? ? ? ? AttrConf: new AttrConf(1,10,128),

? ? ? ? ? ? action: {

? ? ? ? ? ? ? ? toPage(index,limit){

? ? ? ? ? ? ? ? ? ? //實際使用的使用可以通過該方法獲取到當(dāng)前分頁參數(shù)信息

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? error(info){

? ? ? ? ? ? ? ? ? ? console.log(info);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? },

? ? ? ? ? });

? ? ? ? pageUtil3.render({

? ? ? ? ? ? ? AttrConf: new AttrConf(1,10,123),

? ? ? ? ? ? layout: {

? ? ? ? ? ? ? ? left:{

? ? ? ? ? ? ? ? ? ? show: true,

? ? ? ? ? ? ? ? ? ? modules: ['base'],

? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? right:{

? ? ? ? ? ? ? ? ? ? modules:['prev','next','limits','jump'],

? ? ? ? ? ? ? ? }

? ? ? ? ? ? } ? ? ? ?

? ? ? ? ? });


? ? ? ? // 后續(xù)高級用法 等有時間整理好了文檔在補充

? ? ? </script>

? </body>

? </html>

? ```

## 效果預(yù)覽

如有不足之情,?懇請大佬們能在評論區(qū)留下意見?謝謝大家

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容