class Pagination {
constructor(options) {
this.options = Object.assign({
total: 0, // 总数据量
pageSize: 10, // 每页显示数量
currentPage: 1, // 当前页码
showPages: 5, // 显示的页码数量
container: null, // 分页容器元素
onPageChange: null, // 页码改变时的回调函数
}, options);
if (!this.options.container) {
throw new Error("Container element is required.");
}
this.render();
}
render() {
const { total, pageSize, currentPage, showPages, container } = this.options;
const totalPages = Math.ceil(total / pageSize);
// 边界处理
let startPage = Math.max(1, currentPage - Math.floor(showPages / 2));
let endPage = Math.min(totalPages, startPage + showPages - 1);
if (endPage - startPage + 1 < showPages) {
startPage = Math.max(1, endPage - showPages + 1);
}
const fragment = document.createDocumentFragment();
// 首页
this.createPageItem(fragment, 1, '首页', currentPage === 1);
// 上一页
this.createPageItem(fragment, currentPage - 1, '上一页', currentPage === 1);
// 页码
for (let i = startPage; i <= endPage; i++) {
this.createPageItem(fragment, i, i, currentPage === i);
}
// 下一页
this.createPageItem(fragment, currentPage + 1, '下一页', currentPage === totalPages);
// 尾页
this.createPageItem(fragment, totalPages, '尾页', currentPage === totalPages);
// 清空容器
container.innerHTML = '';
container.appendChild(fragment);
}
createPageItem(fragment, page, text, disabled) {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = 'javascript:void(0)'; // 阻止默认跳转
a.textContent = text;
a.classList.toggle('disabled', disabled || page < 1 || page > Math.ceil(this.options.total / this.options.pageSize));
if (!disabled && page >= 1 && page <= Math.ceil(this.options.total / this.options.pageSize)) {
a.addEventListener('click', () => {
this.options.currentPage = page;
this.render();
if (this.options.onPageChange) {
this.options.onPageChange(page);
}
});
}
li.appendChild(a);
fragment.appendChild(li);
}
goToPage(page) {
this.options.currentPage = page;
this.render();
if (this.options.onPageChange) {
this.options.onPageChange(page);
}
}
setTotal(total) {
this.options.total = total;
this.render();
}
}
// 使用示例:
const container = document.getElementById('pagination');
const pagination = new Pagination({
total: 100,
container: container,
onPageChange: (page) => {
console.log('Current page:', page);
// 在这里执行获取数据的操作
}
});
思路:
-
面向对象封装: 使用class封装成一个可复用的Pagination类,方便实例化和管理。
-
参数配置: 通过构造函数options传入参数,包括总数据量、每页数量、当前页码、显示的页码数量、容器元素、页码改变时的回调函数等,使分页组件更灵活。
-
计算总页数:
totalPages = Math.ceil(total / pageSize)
计算总页数,向上取整。 -
计算起始页码和结束页码: 根据当前页码和显示的页码数量计算起始和结束页码,并进行边界处理,确保页码范围的正确性。
-
动态创建DOM元素: 使用
document.createDocumentFragment()
创建文档片段,将生成的页码元素添加到片段中,最后一次性添加到容器中,提高性能。 -
首页、上一页、下一页、尾页: 添加