💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# :-: 一、分页原理 ### 1、基本术语 * 记录索引: 记录在表中的位置,从0开始(与主键无关) * 偏移量: 每页显示的起始位置 * 显示数量: 每页默认的显示数量 ```[mysql] # 为了测试方便,我们先增加一些数据 INSERT INTO `user` VALUES (2, '13011113333', '洪七公', 'e10adc3949ba59abbe56e057f20f883e', 74, 1, 1, 1554282409); INSERT INTO `user` VALUES (3, '18722223333', '黄蓉', 'e10adc3949ba59abbe56e057f20f883e', 17, 2, 1, 1554282409); INSERT INTO `user` VALUES (4, '18722224444', '郭靖', 'e10adc3949ba59abbe56e057f20f883e', 23, 1, 1, 1554282409); INSERT INTO `user` VALUES (5, '18722225555', '黄药师', 'e10adc3949ba59abbe56e057f20f883e', 58, 1, 1, 1554282409); INSERT INTO `user` VALUES (6, '18722226666', '周伯通', 'e10adc3949ba59abbe56e057f20f883e', 53, 1, 1, 1554282409); INSERT INTO `user` VALUES (7, '18722227777', '杨过', 'e10adc3949ba59abbe56e057f20f883e', 1, 1, 1, 1554282409); INSERT INTO `user` VALUES (8, '18722228888', '杨康', 'e10adc3949ba59abbe56e057f20f883e', 22, 1, 1, 1554282409); INSERT INTO `user` VALUES (9, '18722229999', '欧阳锋', 'e10adc3949ba59abbe56e057f20f883e', 60, 1, 1, 1554282409); INSERT INTO `user` VALUES (10, '18733331111', '丘处机', 'e10adc3949ba59abbe56e057f20f883e', 69, 1, 1, 1554282409); INSERT INTO `user` VALUES (11, '18733332222', '瑛姑', 'e10adc3949ba59abbe56e057f20f883e', 45, 1, 1, 1554282409); INSERT INTO `user` VALUES (12, '18733333333', '王重阳', 'e10adc3949ba59abbe56e057f20f883e', 55, 1, 1, 1554282409); INSERT INTO `user` VALUES (13, '18733334444', '穆念慈', 'e10adc3949ba59abbe56e057f20f883e', 19, 1, 1, 1554282409); INSERT INTO `user` VALUES (14, '18733335555', '陈玄风', 'e10adc3949ba59abbe56e057f20f883e', 35, 1, 1, 1554282409); INSERT INTO `user` VALUES (15, '18733336666', '曲灵风', 'e10adc3949ba59abbe56e057f20f883e', 42, 2, 1, 1554282409); INSERT INTO `user` VALUES (16, '18733337777', '梅超风', 'e10adc3949ba59abbe56e057f20f883e', 32, 1, 1, 1554282409); ``` ***** ### 2、SQL中的分页关键字 * `LIMIT m OFFSET n` * `LIMIT m`: 每页显示的记录数量 * `OFFSET n`: 从指定的索引n开始显示 ```mysql SELECT * FROM user; SELECT * FROM user LIMIT 0,5; SELECT * FROM user LIMIT 5,5; SELECT * FROM user LIMIT 5 OFFSET 5; ``` ***** ### 3、偏移量计算公式 * offset = num * (page - 1) ***** # :-: 二、Ajax原理 ### 1、Ajax 是什么 * Ajax: (Asynchronous Javascript And XML)异步JavaScript和XML * Ajax: 是指一种创建交互式网页应用的网页开发技术 * Ajax 是一种用于创建快速动态网页的技术 * Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术 * 通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新 * 这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新 ***** ### 2、XMLHTTPRequest * XMLHttpRequest是一个浏览器接口,使得Javascript可以进行HTTP(S)通信 * 我们最熟悉应用就是创建**AJAX**对象 ***** ### 3、案例 * 在不刷新页面的情况下, 从服务器获取数据并渲染到html中 ```php # php代码:get_cate.php <?php $pdo = new PDO('mysql:dbname=php', 'root','root'); $stmt = $pdo->prepare('SELECT * FROM `category`'); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); echo '<pre>' .print_r($result,true); // echo json_encode($result); ``` ```html # index.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>电影分类</title> </head> <body> <button>电影分类</button> <ul> </ul> </body> <script> var btn = document.getElementsByTagName('button').item(0); // 创建 Ajax对象 var request = new XMLHttpRequest(); btn.addEventListener('click', getCate, false); // btn点击事件回调方法 function getCate(ev) { // 监听请求 request.addEventListener('readystatechange', callBack, false); // 配置请求 request.open('GET', 'get_cate.php', true); // 发送请求 request.send(null); // 从当前按钮上移除点击事件, 防止重复点击 ev.target.removeEventListener('click', getCate, false); } // Ajax的请求成功的回调方法 function callBack() { if (request.readyState === 4) { // 控制台检查 // console.log(request.responseText); var data = JSON.parse(request.responseText); // JSON 转 JS对象 // console.log(data); // 循环生成<li> var ul = document.getElementsByTagName('ul').item(0); data.forEach(function (index){ // console.log(index['alias']); var li = document.createElement('li'); li.innerText = index['alias']; ul.appendChild(li); }); } } </script> </html> ``` ***** # :-: 三、Ajax分页 ### 1. 服务器返回的数据格式 * COUNT 统计表中记录的一个函数,返回匹配条件的行数 * CEIL 浮点数向上取正 * LEFT 从左开始截取字符串 * CONCAT 将多个字符串连接成一个字符串 ```php # php代码:get_movies.php <?php // 获取当前要显示的页数 $page = intval($_GET['p'] ?? 1); $pdo = new PDO('mysql:dbname=php', 'root', 'root'); // 每页显示数量 $num = 5; // 总页数: 需要分二步, 第一求出总记录数量, 第二总记录数量除以每页显示的记录数量,再向上取整 $sql = "SELECT CEIL(COUNT(`mov_id`)/{$num}) FROM `movies`"; $stmt = $pdo->prepare($sql); $stmt->execute(); $pages = $stmt->fetchColumn(0); // 每页的显示起止位置: 偏移量 // 偏移量 = 当前显示数量 * (当前页码 - 1) $offset = $num * ($page - 1); $sql = "SELECT `mov_id`,`name`, CONCAT(LEFT(`detail`,20),'...') AS `detail` FROM `movies` LIMIT {$num} OFFSET {$offset} "; $stmt = $pdo->prepare($sql); $stmt->execute(); $movies = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['pages'=>$pages, 'movies'=>$movies]); ``` ***** ### 2. 前端分页条 ```php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>最新影视剧介绍</title> <style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid black; } thead > tr{ background-color: lightblue; } ul, li { padding: 0; margin: 5px auto; list-style: none; text-align: center; overflow: hidden; } li { display: inline-block; width: 30px; height: 20px; border: 1px solid black; margin-left: 3px; } li:hover { background-color: lightblue; cursor: pointer; } /*设置当前页高亮样式*/ .active { background-color: lightblue; } </style> </head> <body> <table> <caption>最新影视剧介绍</caption> <thead> <tr> <th>序号</th> <th>片名</th> <th>简介</th> </tr> </thead> <tbody id> <!--这里显示影视信息列表--> <tr> <td>3</td> <td>如果可以这样爱</td> <td>一对已婚男女突然徇情自杀,以为可以结束这...</td> </tr> </tbody> </table> <ul> <li class="active">1</li> <li class="">2</li> </ul> </body> </html> ``` ### 3. 数据获取与渲染 ```php <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>最新影视剧介绍</title> <style> table { border-collapse: collapse; width: 100%; } th, td { border: 1px solid black; } thead > tr{ background-color: lightblue; } ul, li { padding: 0; margin: 5px auto; list-style: none; text-align: center; overflow: hidden; } li { display: inline-block; width: 30px; height: 20px; border: 1px solid black; margin-left: 3px; } li:hover { background-color: lightblue; cursor: pointer; } /*设置当前页高亮样式*/ .active { background-color: lightblue; } </style> </head> <body> <table> <caption>最新影视剧介绍</caption> <thead> <tr> <th>序号</th> <th>片名</th> <th>简介</th> </tr> </thead> <tbody id> <!--这里显示影视信息列表--> </tbody> </table> <ul> <!--这里翻页--> </ul> </body> </html> <script> // 获取表格显示区 var tbody = document.getElementsByTagName('tbody').item(0); // 获取页码显示区 var ul = document.getElementsByTagName('ul').item(0); // 当前页码: 默认显示第一页 var p = <?=$_GET['p'] ?? 1?>; // 创建 Ajax对象 var request = new XMLHttpRequest(); // 监听文档的load事件,在页面加载完成后通过Ajax方式获取数据 window.addEventListener('load', showData, false); // load事件方法 function showData() { // 监听Ajax成功回调 request.addEventListener('readystatechange', getData, false); // 配置请求 request.open('GET', 'get_movies.php?p='+p, true); // 发送请求 request.send(null); } function getData() { if (request.readyState === 4) { // console.log(request.responseText); // 1. 获取Ajax返回的数据并解析为JavaScript变量 var obj = JSON.parse(request.responseText); var pages = obj['pages']; var movies = obj['movies']; // 2. 生成表格数据 var str = ''; movies.forEach(function (movie) { str += '<tr>'; str += '<td>' + movie['mov_id']+ '</td>'; str += '<td>' + movie.name+ '</td>'; str += '<td>' + movie.detail+ '</td>'; str += '</tr>'; }); // 将数据添加到表格中 tbody.innerHTML = str; // 性能优化建议: 使用文档片段统一添加,以减少DOM操作,提升渲染效率 // var frag = document.createDocumentFragment(); // movies.forEach(function (movie) { // var tr = document.createElement('tr'); // for (var key in movie) { // var td = document.createElement('td'); // td.innerHTML = movie[key]; // tr.appendChild(td); // } // frag.appendChild(tr); // }); // tbody.appendChild(frag); // 3. 生成页码 for (var i = 1; i <= pages; i++) { // 设置当前页码是否高亮? var active = (i === p) ? 'active' : ''; ul.innerHTML += '<li class="'+ active +'">' + i + '</li>'; // 供参考的,规范的DOM语法 /* var li = document.createElement('li'); li.appendChild(document.createTextNode(i.toString())); if (p === i) li.classList.add('active'); ul.appendChild(li); */ } } } // 给页码添加点击事件 ul.addEventListener('click', set_page, false); function set_page(ev) { console.log(ev.target.innerText); location.search = '?p=' + ev.target.innerText; } // 作业: // 添加上一下, 下一页功能, 注意判断页码越界的问题, 例如到了第一页再前翻怎么处理, 到了最后一页再后翻如何处理? </script> ```