纯js实现一个带分页表格

表格由三部分组成,表格头部,表格体,表格的分页栏。本文实现的分页表格,适合后端返回所有数据后,采用前端分页。数据如果有更新,需要手动调用更新方法

表格和分页的html部分

<div id="tableContainer" style="overflow: scroll; width: 100%;">
   <table id="'table" width="1000px" class="tableClass">
      <thead id="thead"></thead>
      <tbody id="tbody"></tbody>
   </table>
</div>
<div class="pagination-nav">
   <ul class="pagination" id="pagination"></ul>
</div>

css样式部分



ul {
  list-style: none;
  margin: 0px;
  padding: 0px;
}

body {
  margin: 0;
}

.tableClass {
  min-width: 400px;
  border: 1px solid red;
  overflow-x: scroll;
}

.tableClass {
  font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  border-collapse: collapse;
  width: 100%;
  margin-left: 2px;
  margin-right: 2px;
}

.tableClass td, .tableClass th {
  border: 1px solid #ddd;
  padding: 2px;
  min-width: 60px;
}

.tableClass tr {background-color: #f2f2f2;}
/* .tableClass tr:nth-child(odd){background-color: #f2f2f2;} */

.tableClass tr:nth-child(5n){background-color: #dfebdb;}

.tableClass tr:hover {background-color: #ddd;}

.tableClass th {
  /* padding-top: 12px;
  padding-bottom: 12px; */
  text-align: left;
  background-color: #4CAF50;
  color: white;
}


#tableContainer ::-webkit-scrollbar {
  width: 8px;
  height: 8px;  
}

#tableContainer ::-webkit-scrollbar-thumb {
  background-color: rgba(71, 71, 71, 0.63);
  border-radius: 4px;
}

.pagination-nav {
  margin-top: 5px;
  margin-bottom: 5px;
  border-radius: 6px;
  padding: 0;
  display: flex;
}

.pagination {
    display: -ms-flexbox;
    display: flex;
    padding-left: 2px;
    list-style: none;
    border-radius: 0.25rem;
}

#pageCurrentInfo {
  line-height: 30px;
  font-size: 16px;
  color: wheat;
}
.active {
  background-color: #007bff!important;
  color: white!important;
}

.page-link {
  position: relative;
  display: block;
  padding: 0.25rem 0.75rem;
  margin-left: -1px;
  line-height: 1.25;
  text-decoration:none;
  color: #007bff;
  background-color: #fff;
  border: 1px solid #dee2e6;
}
.page-item:first-child .page-link {
  margin-left: 0;
  border-top-left-radius: 0.25rem;
  border-bottom-left-radius: 0.25rem;
}

.page-item:last-child .page-link {
  margin-left: 0;
  border-top-right-radius: 0.25rem;
  border-bottom-right-radius: 0.25rem;
}

::-webkit-scrollbar {
  width: 8px;
  height: 8px;  
}

::-webkit-scrollbar-thumb {
  background-color: rgba(71, 71, 71, 0.63);
  border-radius: 4px;
}

js部分

分页逻辑是,>1页,展示分页,5页以内,展示5个页码,超出5页,展示“向前”,“向后”,以及包括点击页的相邻5页的页码。

var paginationUl = document.getElementById('pagination');
var tableHead = document.getElementById('thead')
var tableBody = document.getElementById('tbody')

paginationUl.addEventListener('click', event => {
  let page = event.target.dataset.page;
  if(page === 'prev') {
    tableObj.curPage > 1 ? tableObj.updateTableRowsByPageNum(tableObj.curPage-1, true) : null;
  }else if(page === 'next') {
    tableObj.curPage < tableObj.total ? tableObj.updateTableRowsByPageNum(tableObj.curPage+1, true) : null;
  }else {
    clearLiActive();
    event.target.classList.add('active');
    tableObj.updateTableRowsByPageNum(parseInt(event.target.dataset.page), false)
  }
})
// 清除li的active
function clearLiActive() {
  let activeli =Array.from(paginationUl.childNodes).filter(node => node.firstChild.className.includes('active'));
  activeli.length > 0 ? activeli[0].firstChild.classList.remove('active') : null;
}

function createPagination(pageNum, activePage = 1) {
  let str = ''
  if(pageNum <= 5) {
    for(let i = 1; i <= pageNum; i++) {
      let className = i===activePage ? "page-link active" : "page-link"
      str += '<li class="page-item">' + '<a class="'+ `${className}` +'" href="#" data-page=' + i + ' >' + i + '</a></li>'
    }
  }else {
    str += '<li class="page-item">' + '<a class="page-link" href="#" data-page=' + 'prev' + ' >' + '<' + '</a></li>'
    for(let i = Math.min(activePage, pageNum-4); i < Math.min(5 + activePage, pageNum+1); i++) {
      let className = i===activePage ? "page-link active" : "page-link"
      str += '<li class="page-item">' + '<a class="' + className +'" href="#" data-page=' + i + ' >' + i + '</a></li>'
    }
    str += '<li class="page-item">' + '<a class="page-link" href="#" data-page=' + 'next' + ' >' + '>' + '</a></li>'
  }
  paginationUl.innerHTML = str;
}


class MyTable {
  constructor(columns, pageSize, data) {
    this.columns = columns;
    this.pageSize = pageSize;
    this.curPage = 1;
    this.total = 1; // 总页数
    this.data = data;
    this.tableHeadDom = null;
    this.tableBodyDom = null;
  }
  init(headDom, bodyDom) {
    this.tableHeadDom = headDom;
    this.tableBodyDom = bodyDom;
    this.iniTableHeader(this.tableHeadDom);
    this.updateTableRowsByPageNum(this.curPage);
  }

  iniTableHeader(target) {
    let str = '<tr>'
    for(let item of this.columns) {
      str += '<th>' + item.title + '</th>'
    }
    target.innerHTML = str + '</tr>'
  }
  createTableRowsToTarget(target, data) {
    let arr = []
    for(let i = 0, size = data.length; i < size; i++) {
      let str = '<tr>';
      for(let item of this.columns) {
        str += '<td>' + data[i][item.field] + '</td>'
      }
      arr.push(str.concat('</tr>'))
    }
    target.innerHTML = arr.join('')
  }
  //更新第pageNo页数据,第二个参数代表更新分页
  updateTableRowsByPageNum(pageNo, updatePagination = true) {
    console.log(pageNo, this.data, this.pageSize, updatePagination)
    this.curPage = pageNo;
    let pageNum = Math.ceil(this.data.length/this.pageSize);
    if(pageNum !== this.total) {
      this.total = pageNum;
    }
    if(pageNum >= 2) {
      updatePagination && createPagination(pageNum, pageNo)
    }
    this.createTableRowsToTarget(this.tableBodyDom, this.data.slice((pageNo - 1) * this.pageSize, pageNo * this.pageSize))
  }
}

使用MyTable类

// 表格的列,field为字段名,title为展示的表头
var tableColumns = [
  {
    field: 'id',
    title: 'ID'
  },
  {
    field: 'KeyFactor1',
    title: '因素1'
  },
  {
    field: 'KeyFactor2',
    title: '因素2'
  },
  {
    field: 'KeyFactor3',
    title: '因素3'
  },
  {
    field: 'KeyFactor4',
    title: '因素4'
  },
  {
    field: 'KeyFactor5',
    title: '因素5'
  },
]
var data = mockTableData(tableColumns.map(item => item.field), 20)
var tableObj = new MyTable(tableColumns, 3, data)
tableObj.init(tableHead, tableBody)

// 构造模拟数据,columns为数组,如['a', 'b', 'c']
function mockTableData(columns, size = 50) {
  let arr = [];
  for(let i = 0; i < size; i++) {
    let row = columns.reduce((prev, cur) => {
      prev[cur] = Math.random().toFixed(3);
      return prev;
  }, {});
  arr.push(row);
  }
  return arr;
}

如果data有更新,可以手动调用   tableObj.updateTableRowsByPageNum(1);//更新第一页数据

后续改进点,加入支持后端分页,点击页数,请求数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值