如何不依赖jQuery实现Bootstrap 5分页 支持分页长度、搜索等特性
Bootstrap 5 卡片分页+搜索+页长设置完整实现方案
提前在项目中引入 Bootstrap 5 的 CSS 和 JS 基础资源即可使用以下代码。
1. HTML 结构
<div class="container my-4"> <!-- 顶部控制栏 --> <div class="row g-3 mb-4"> <div class="col-md-6"> <input type="text" id="searchInput" class="form-control" placeholder="搜索卡片标题/内容..."> </div> <div class="col-md-6 text-md-end"> <select id="pageSizeSelect" class="form-select d-inline-block w-auto"> <option value="5">每页5条</option> <option value="10">每页10条</option> <option value="20">每页20条</option> </select> </div> </div> <!-- 卡片容器 --> <div id="cardContainer" class="row g-4 mb-4"></div> <!-- 分页容器 --> <nav aria-label="卡片分页"> <ul id="paginationContainer" class="pagination justify-content-center"></ul> </nav> </div>
2. JS 逻辑实现
// 模拟真实卡片数据,可替换为后端接口返回的实际数据 const cardData = Array.from({length: 30}, (_, index) => ({ id: index + 1, title: `卡片${index + 1}`, content: `这是第${index + 1}张卡片的描述内容,关联标签:测试${index % 6}` })) // 全局状态变量 let currentPage = 1 let pageSize = 5 let filteredData = [...cardData] // 渲染卡片列表 function renderCards() { const start = (currentPage - 1) * pageSize const end = start + pageSize const pageData = filteredData.slice(start, end) const cardContainer = document.getElementById('cardContainer') cardContainer.innerHTML = '' if (pageData.length === 0) { cardContainer.innerHTML = `<div class="col-12 text-center py-5">没有匹配的卡片数据</div>` return } pageData.forEach(item => { const cardCol = document.createElement('div') cardCol.className = 'col-md-4 col-lg-3' cardCol.innerHTML = ` <div class="card h-100"> <div class="card-body"> <h5 class="card-title">${item.title}</h5> <p class="card-text">${item.content}</p> </div> </div> ` cardContainer.appendChild(cardCol) }) } // 渲染分页组件 function renderPagination() { const totalPages = Math.ceil(filteredData.length / pageSize) const paginationContainer = document.getElementById('paginationContainer') paginationContainer.innerHTML = '' // 上一页按钮 const prevLi = document.createElement('li') prevLi.className = `page-item ${currentPage === 1 ? 'disabled' : ''}` prevLi.innerHTML = `<a class="page-link" href="#" aria-label="上一页">上一页</a>` prevLi.addEventListener('click', (e) => { e.preventDefault() if (currentPage > 1) { currentPage-- renderCards() renderPagination() } }) paginationContainer.appendChild(prevLi) // 页码按钮 for (let i = 1; i <= totalPages; i++) { const pageLi = document.createElement('li') pageLi.className = `page-item ${i === currentPage ? 'active' : ''}` pageLi.innerHTML = `<a class="page-link" href="#">${i}</a>` pageLi.addEventListener('click', (e) => { e.preventDefault() currentPage = i renderCards() renderPagination() }) paginationContainer.appendChild(pageLi) } // 下一页按钮 const nextLi = document.createElement('li') nextLi.className = `page-item ${currentPage === totalPages || totalPages === 0 ? 'disabled' : ''}` nextLi.innerHTML = `<a class="page-link" href="#" aria-label="下一页">下一页</a>` nextLi.addEventListener('click', (e) => { e.preventDefault() if (currentPage < totalPages) { currentPage++ renderCards() renderPagination() } }) paginationContainer.appendChild(nextLi) } // 搜索功能绑定 document.getElementById('searchInput').addEventListener('input', (e) => { const keyword = e.target.value.trim().toLowerCase() filteredData = cardData.filter(item => item.title.toLowerCase().includes(keyword) || item.content.toLowerCase().includes(keyword) ) currentPage = 1 renderCards() renderPagination() }) // 页长设置绑定 document.getElementById('pageSizeSelect').addEventListener('change', (e) => { pageSize = parseInt(e.target.value) currentPage = 1 renderCards() renderPagination() }) // 初始化渲染 renderCards() renderPagination()
3. 支持的功能说明
- 搜索功能:输入关键词后实时模糊匹配卡片标题和内容,无匹配结果时显示空提示,搜索后自动回到第一页
- 页长设置:可自由切换每页展示5/10/20条数据,切换后自动调整分页结构,回到第一页
- 分页交互:支持上一页/下一页跳转、指定页码直达,边界状态下(第一页的上一页、最后一页的下一页)按钮自动禁用,当前页码高亮显示
- 适配Bootstrap 5原生样式:所有UI组件完全复用Bootstrap 5原生样式,无需额外自定义CSS
内容的提问来源于stack exchange,提问作者Goutham Harshith
相关产品推荐
相关产品推荐

