> 最近在閱讀公司項目代碼的時候, 發(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ū)留下意見?謝謝大家