如何为分页组件添加符合指定逻辑的省略号(Ellipsis)
如何为分页组件添加符合指定逻辑的省略号(Ellipsis)
嘿,我看了你这个分页的需求,刚好可以通过修改paginate函数里生成页码数组的逻辑,再配合调整渲染代码来实现你要的省略号效果,咱们一步步来:
第一步:修改paginate函数生成带省略号的页码数组
原来的pages数组只是生成了连续的页码范围,现在咱们要根据startPage、endPage和totalPages的关系,插入省略号和首尾页码,完全匹配你要的逻辑:
function paginate(totalItems, currentPage = 1, pageSize = 2, maxPages = 3) { let totalPages = Math.ceil(totalItems / pageSize); if (currentPage < 1) { currentPage = 1; } else if (currentPage > totalPages) { currentPage = totalPages; } let startPage, endPage; if (totalPages <= maxPages) { startPage = 1; endPage = totalPages; } else { let maxPagesBeforeCurrentPage = Math.floor(maxPages / 2); let maxPagesAfterCurrentPage = Math.ceil(maxPages / 2) - 1; if (currentPage <= maxPagesBeforeCurrentPage) { startPage = 1; endPage = maxPages; } else if (currentPage + maxPagesAfterCurrentPage >= totalPages) { startPage = totalPages - maxPages + 1; endPage = totalPages; } else { startPage = currentPage - maxPagesBeforeCurrentPage; endPage = currentPage + maxPagesAfterCurrentPage; } } let startIndex = (currentPage - 1) * pageSize; let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1); // 重点:生成带省略号的页码数组 let pages = []; // 处理开头的第一页和省略号 if (startPage > 1) { pages.push(1); // 如果起始页大于2,才加省略号(避免出现1,...2这种奇怪情况) if (startPage > 2) { pages.push('...'); } } // 添加中间的连续页码 pages.push(...Array.from(Array((endPage + 1) - startPage).keys()).map(i => startPage + i)); // 处理结尾的省略号和最后一页 if (endPage < totalPages) { // 如果结束页小于总页数减1,才加省略号(避免出现35,...36这种情况) if (endPage < totalPages - 1) { pages.push('...'); } pages.push(totalPages); } console.log(totalItems, currentPage, pageSize, totalPages, startPage, endPage, startIndex, endIndex, pages); return { totalItems: totalItems, currentPage: currentPage, pageSize: pageSize, totalPages: totalPages, startPage: startPage, endPage: endPage, startIndex: startIndex, endIndex: endIndex, pages: pages }; }
第二步:修改分页渲染逻辑,适配省略号
现在pages数组里既有数字页码,也有'...'字符串,咱们得区分渲染:省略号是不可点击的,所以要生成禁用状态的列表项,不能绑定点击事件:
function setHTML(items) { wrapper.innerHTML = "" pagination.innerHTML = "" const { totalItems, currentPage, pageSize, totalPages, startPage, endPage, startIndex, endIndex, pages } = paginate(items.length, currPage, 4, 3); const ul = document.createElement("ul"); ul.classList.add('pagination'); let paginationHTML = ""; paginationHTML += `<li class="page-item ${currentPage === 1 ? 'disabled' : 'page-prev'}"><a class="page-link" href="#">Previous</a></li>` // 重点:区分渲染页码和省略号 pages.forEach(page => { if (page === '...') { // 渲染不可点击的省略号 paginationHTML += `<li class="page-item disabled"><span class="page-link">...</span></li>`; } else if (currentPage === page) { // 渲染当前激活的页码 paginationHTML += `<li class="page page-item active" data-page="${page}"><a class="page-link" href="#" aria-current="page">${page}</a></li>`; } else { // 渲染普通可点击页码 paginationHTML += `<li class="page page-item" data-page="${page}"><a class="page-link" href="#">${page}</a></li>`; } }) paginationHTML += `<li class="page-item ${currentPage === totalPages ? 'disabled' : 'page-next'}"><a class="page-link" href="#">Next</a></li>` ul.innerHTML = paginationHTML; pagination.append(ul); const start = (currentPage - 1) * pageSize, end = currentPage * pageSize; items.slice(start, end).forEach(el => { wrapper.append(el) }) }
最后测试一下
这样修改之后,你的分页就会完全按照你要的逻辑显示:
- 当前页在1-3区间时,显示
1, 2, 3, ..., 36 - 当前页在中间的10-12区间时,显示
1, ..., 10, 11, 12, ..., 36 - 当前页在34-36区间时,显示
1, ..., 34, 35, 36
点击页码、上一页/下一页的功能也都能正常工作,省略号是禁用状态不会触发跳转~
内容来源于stack exchange
相关产品推荐
相关产品推荐

