简易分页功能实现
分页是一种常见的前端功能,特别是在需要展示大量数据时。它通过将数据分割成多个页面,帮助用户更容易浏览并提高页面加载性能。本文将介绍一个简易分页的实现思路及其代码实现,旨在帮助开发者快速理解并实现分页功能。
功能概述
这个示例实现了一个简单的分页功能,包括以下主要功能:
- 数据分页显示:根据每页的条数和当前页显示相应的数据。
- 分页控件:展示当前页信息,并允许用户通过上一页、下一页按钮或直接跳转到指定页面进行浏览。
- 自定义每页显示的条数:用户可以选择每页显示不同条数的数据。
- 跳转页功能:用户可以直接输入页码跳转到指定的页面。
- 警告提示:如果输入的页码超出有效范围,会弹出警告提示。
核心思路
-
数据存储与加载:
- 数据以JSON格式存储,并通过
XMLHttpRequest
请求加载到前端。 - 数据加载完成后,进行分页展示。
- 数据以JSON格式存储,并通过
-
分页计算:
- 根据总数据量和每页数据量,计算出总页数。
- 使用当前页的索引(从0开始)来确定需要展示的数据范围。
-
渲染表格与分页控件:
- 在表格中展示当前页的数据。
- 在底部渲染分页控件,显示当前页数、总页数以及每页显示的条数等信息。
- 动态生成页码链接,根据用户的选择更新页面。
-
用户交互:
- 提供上一页、下一页按钮以及页码跳转功能。
- 用户可以通过选择每页显示的数据条数来调整显示内容。
代码实现
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>简易分页</title><style>/* 表格设置宽高 */.boxes {width: 60%;height: 100%;margin: auto;text-align: center;}.item {min-height: 200px;max-height: 700px;overflow: auto;}/* 设置行高 */.itemes {line-height: 200%;}/* 底部导航栏 */.box {width: 80%;height: 30px;display: flex;margin: 1% auto;justify-content: space-between;line-height: 30px;}.box>button {width: 30px;cursor: pointer;border: none;font-size: 20px;}.pages>span {padding: 3px 8px;cursor: pointer;}input {width: 30px;margin: 4px;}/* 弹出警告窗口 */.warning {width: 25%;height: 50px;border-radius: 10px;box-shadow: 1px 2px 10px lightgray;padding-left: 20px;position: fixed;right: 0;background-color: #fde2e2;color: #f56c6c;display: none;}.title {font-weight: 600;}</style></head><body><!-- 警告弹出窗 --><div class="warning"><div class="title">错误</div><div>没有当前页数,请重新输入</div></div><!-- 表格 --><div class="item"><table class="boxes" cellspacing="0"><thead><tr><th>id</th><th>内容</th><th>标题</th></tr></thead><tbody></tbody></table></div><!-- 底部导航栏 --><div class="box"></div><script>let k = 0; // 当前页let data; // 存储数据let num = 5; // 每页显示的数据条数let total = 0; // 总页数let main = document.getElementsByTagName('tbody')[0]; // 获取表格主体let foot = document.getElementsByClassName('box')[0]; // 获取分页底部// 创建 XMLHttpRequest 获取数据let xhr = new XMLHttpRequest();xhr.open('get', './js/paging.json', true);xhr.send();// 当数据请求完成时,处理响应xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {data = JSON.parse(xhr.responseText); // 解析 JSON 数据console.log(data);renderTable(); // 渲染表格}};// 渲染表格内容function renderTable() {let str = '';for (let i = k * num; i < (k + 1) * num; i++) {if (i >= data.length) break; // 防止超出数据范围str += `<tr class="itemes"><td>${data[i].id}</td><td>${data[i].name}</td><td>${data[i].title}</td></tr>`;}main.innerHTML = str; // 将内容插入表格renderPagination(); // 渲染分页}// 渲染分页控件function renderPagination() {let strs = '';total = Math.ceil(data.length / num); // 计算总页数strs += `<span>第${k + 1}页/共${total}页</span><span>当前${num}条/共${data.length}条数据</span><select onchange="changeItemsPerPage(value)"><option value="${num}">${num}条/页</option><option value="5">5条/页</option><option value="15">15条/页</option><option value="30">30条/页</option><option value="45">45条/页</option><option value="60">60条/页</option></select><button onclick="lastPage()"> < </button><!-- 不要学博主,这边建议用图标,因为可能会被识别成比较运算符 --><div class="pages">`;// 生成页码if (total < 6) {for (let i = 0; i < total; i++) {strs += createPageLink(i);}} else {if (k < 3) {for (let i = 0; i < 5; i++) {strs += createPageLink(i);}strs += `...`;} else if (k > total - 4) {strs += `...`;for (let i = total - 5; i < total; i++) {strs += createPageLink(i);}} else {strs += `...`;for (let i = k - 2; i <= k + 2; i++) {strs += createPageLink(i);}strs += `...`;}}strs += `</div><button onclick="nextPage()"> > </button><!-- 不要学博主,这边建议用图标,因为可能会被识别成比较运算符 --><span>前往第<input type="text" id="input" onchange="goToPageInput()"/>页</span>`;foot.innerHTML = strs;}// 创建页码链接function createPageLink(page) {return `<span class="tail_page" onclick="goToPage(${page})" ${k === page ? 'style="color:#4DAAFF;"' : ''}>${page + 1}</span>`;}// 上一页function lastPage() {if (k > 0) {k--;renderTable();}}// 下一页function nextPage() {if (k < total - 1) {k++;renderTable();}}// 改变每页显示条数function changeItemsPerPage(value) {num = parseInt(value);k = 0; // 每次改变每页显示条数时,返回第一页renderTable();}// 跳转到指定页function goToPageInput() {let input = document.getElementById('input');let warn = document.getElementsByClassName('warning')[0]; // 获取警告信息元素let page = parseInt(input.value); // 获取输入的页码if (page > 0 && page <= total) {k = page - 1; // 跳转到指定页面renderTable();} else {warn.style.display = 'block'; // 显示警告信息input.value = ''; // 清空输入框setTimeout(() => {warn.style.display = 'none'; // 隐藏警告信息}, 3000);}}// 跳转到指定页(点击页码时调用)function goToPage(page) {k = page;renderTable();}</script></body>
</html>
JSON假数据(可更改):
[{"id": 1,"name": "路易威登","title": "老花手袋"},{"id": 2,"name": "Cartier","title": "卡地亚猎豹系列"},{"id": 3,"name": "海瑞温斯顿","title": "The One系列"},{"id": 4,"name": "宝格丽","title": "B.zero1系列"},{"id": 5,"name": "MiuMiu","title": "保龄球包"},{"id": 6,"name": "纪梵希","title": "纪梵希热流香水"},{"id": 7,"name": "古驰","title": "Dionysus 酒神包"},{"id": 8,"name": "YSL圣罗兰","title": "小金条1966"},{"id": 9,"name": "梵克雅宝","title": "四叶草手链"},{"id": 10,"name": "FENDI","title": "经典手袋"},{"id": 11,"name": "DIOR","title": "马鞍包"},{"id": 12,"name": "CHNAEL","title": "香奈儿5号"},{"id": 13,"name": "狐妖小红娘","title": "涂山容容"},{"id": 14,"name": "百妖谱","title": "桃夭"},{"id": 15,"name": "假面超人","title": "假面骑士"},{"id": 16,"name": "眷思量","title": "镜玄丽娘"},{"id": 17,"name": "蜡笔小新","title": "野原美冴"},{"id": 18,"name": "来往不逢人,长歌楚天碧","title": "柳宗元"},{"id": 19,"name": "念天地之悠悠,独怆然而泪下","title": "陈子昂"},{"id": 20,"name": "旧时王谢堂前燕,飞入寻常百姓家","title": "白居易乌衣巷"},{"id": 21,"name": "白日依山尽,黄河入海流","title": "王之涣"},{"id": 22,"name": "君言不得意,归卧南山陲","title": "王维"},{"id": 23,"name": "人生不相见,动如参与商","title": "杜甫赠卫八处士"},{"id": 24,"name": "寒雨连江夜入吴,平明送客楚山孤","title": "王昌龄"},{"id": 25,"name": "海客谈瀛洲,烟涛微茫信难求","title": "李白梦游天姥吟留别"},{"id": 26,"name": "落魄江湖载酒行,楚腰纤细掌中轻","title": "杜牧遣怀"},{"id": 27,"name": "故人具鸡黍,邀我至田家","title": "孟浩然"},{"id": 28,"name": "荡胸生曾云,决眦入归鸟","title": "杜甫"},{"id": 29,"name": "塔势如涌出,孤高耸天宫","title": "岑参与高适薛据同登慈恩寺浮图"},{"id": 30,"name": "臣本布衣,躬耕于南阳","title": "诸葛亮"},{"id": 31,"name": "东临碣石,以观沧海","title": "曹操"},{"id": 32,"name": "小楼昨夜又东风","title": "李煜"},{"id": 33,"name": "沙湖道中遇雨,同行皆狼狈","title": "苏轼"},{"id": 34,"name": "笑谈渴饮匈奴血","title": "岳飞"},{"id": 35,"name": "而来四万八千岁,不与秦塞通人烟","title": "蜀道难"},{"id": 36,"name": "住近湓江地低湿,黄芦苦竹绕宅生","title": "琵琶行"},{"id": 37,"name": "谈笑有鸿儒,而来无白丁","title": "陋室铭"},{"id": 38,"name": "阴风怒号,浊浪排空,日星隐曜","title": "岳阳楼记"},{"id": 39,"name": "闲云潭影日悠悠,物换星移几度秋","title": "滕王阁序"},{"id": 40,"name": "六王毕,四海一,蜀山兀,阿胖出","title": "阿房宫赋"},{"id": 41,"name": "海绵宝宝","title": "章鱼哥"},{"id": 42,"name": "fate","title": "阿尔托莉雅.潘德拉贡"},{"id": 43,"name": "第五人格","title": "红夫人"},{"id": 44,"name": "间谍过家家","title": "约尔"},{"id": 45,"name": "进击的巨人","title": "伊雷娜"},{"id": 46,"name": "及尔偕老,老使我怨","title": "氓"},{"id": 47,"name": "行道迟迟,载渴载饥。","title": "采薇"},{"id": 48,"name": "最是一年春好处,绝胜烟柳满皇都","title": "早春呈水部张十八员外"},{"id": 49,"name": "劝君更尽一杯酒,西出阳关无故人","title": "送元二使西安"},{"id": 50,"name": "明月装饰了你的窗子你装饰了别人的梦","title": "断章"},{"id": 51,"name": "天气你好样的","title": "白天晒毁我晚上吹飞我"},{"id": 52,"name": "超绝混搭风","title": "棉袄配睡裤"},{"id": 53,"name": "再也不玩抽象了","title": "第一真的有人拿我当沙贝,第二没人懂我的幽默"},{"id": 54,"name": "微笑","title": "爱笑的人法令纹不会太浅"},{"id": 55,"name": "我是皇帝","title": "啊哈:吾皇万岁万岁万万岁"}
]