博客列表 >JS基础-jQuery操作ajax/无刷新分页小实战

JS基础-jQuery操作ajax/无刷新分页小实战

岂几岂几
岂几岂几原创
2020年06月08日 23:51:11785浏览

1. jQuery操作ajax

    1. load(): 加载HTML片段, 即把其他HTML页面文件加载进来, 加载方式: 异步, GET方式加载
    • load()函数加载的外部代码片段, 会直接作为调用load()方法的子元素, 不能反悔相应的代码片段字符串.
    1. $.get(url, data, callback): 以get的方式从服务器获取资源/数据
    1. $.post(url, data, callback): 以post的方式从服务器获取资源/数据, 使用方法跟get很类似
    1. $.getJSON(url, data, callback): 以get的方式从服务器获取JSON格式的数据, 并转换成js对象.
    • 跟普通的get请求不同的点: getJSON()方法会自动把返回的字符串转换为JSON对象, 再传入回调函数中, 即, 自动执行var data = JSON.parse(res)语句, 得到的data是一个JS对象数据.
    1. $ajax(): 能实现上面2到4的方法, 实际上掌握这个方法即可.
    • 五个常用对象字面量参数:
      • type: 请求类型, 即: GET, POST
      • url: 请求的url
      • data: 发送的数据, 若是GET请求, 数据可以放到url上, 而POST请求必须放到data这里
      • dataType: 期望服务器返回/相应的数据类型(大部分场景可以自己判断)
      • success: function(data) {// 回调函数...函数参数的data是服务器返回的数据}
    1. $.ajax()-jsonp: 使用$.ajax()发送跨域请求
    • url参数中的jsonp参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符, 请求成功后, 会用success指定的回调函数来填充?占位符.
    • 如果不想用success指定的回调函数来填充?占位符, 也可以用jsonpCallback参数指定一个本地函数来填充?占位符.

第一个按钮加载的外部HTML代码片段nav.html

  1. <ul>
  2. <li>首页</li>
  3. <li>PHP</li>
  4. <li>HTML</li>
  5. <li>CSS</li>
  6. <li>JavaScript</li>
  7. </ul>

第二至第五个按钮发送的请求访问的模拟数据库查询文件users.php

  1. <?php
  2. // 模拟数据库
  3. $users = [
  4. ['id' => 1, 'name' => 'zhangsan', 'age' => 33],
  5. ['id' => 2, 'name' => 'lisi', 'age' => 23],
  6. ['id' => 3, 'name' => 'wangwu', 'age' => 35],
  7. ['id' => 4, 'name' => 'zhaoliu', 'age' => 39],
  8. ];
  9. $id = intval($_REQUEST['id']);
  10. if(in_array($id, array_column($users, 'id'))) {
  11. foreach($users as $user) {
  12. if($user['id'] == $id) {
  13. // 以自定义格式字符串返回(按钮2, 3)
  14. // vprintf('%s : %s %s 岁', $user);
  15. // 以JSON格式字符串返回(按钮4)
  16. echo json_encode($user);
  17. }
  18. }
  19. } else {
  20. echo "<span style='color: red'>没有找到</span>";
  21. }

第六/第七个按钮访问的查询数据库脚本文件

  1. <?php
  2. // 这里返回json数据, 而json只支持utf8编码
  3. header('content-type: text/html;charset=utf-8');
  4. // 模拟根据id值获取数据, 并调用回调函数处理数据
  5. // 获取请求参数(jsonp指定一个回调函数名)
  6. $callback = $_GET['jsonp'];
  7. $id = $_GET['id'];
  8. // 返回的处理结果数组
  9. $res = [
  10. 'status' => '1',
  11. 'message' => '查询成功',
  12. ];
  13. // 判断id值是否有效
  14. if(!filter_var($id, FILTER_VALIDATE_INT, ['option' => ['min_range' => 1]])) {
  15. $res['status'] = '0';
  16. $res['message'] = 'ID值无效';
  17. }
  18. // 连接数据库
  19. $pdo = new PDO('mysql:host=localhost;dbname=phpedu;charset=utf8;port=3306', 'root', 'root');
  20. // 查询
  21. $stmt = $pdo->query("SELECT * FROM `player` WHERE `id` = {$id}");
  22. // 判断是否查到值
  23. if(!$stmt || $stmt->rowCount < 1) {
  24. // 没查到的处理
  25. $res['status'] = '0';
  26. $res['message'] = 'ID值无效';
  27. } else {
  28. // 查到数据
  29. $res['data'] = $stmt->fetch(PDO::FETCH_ASSOC);
  30. }
  31. // 打印回调
  32. echo $callback . '(' . json_encode(json_encode($res)) . ')';

jQuery操作ajax实例文件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>jQuery中操作ajax</title>
  7. <!-- CDN方式引用, 即内容分发方式 -->
  8. <!-- BootCDN或者又拍云的CDN的速度都可以 -->
  9. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
  10. <!-- 本地引用 -->
  11. <style>
  12. body {
  13. height: 100vh;
  14. width: 100vw;
  15. display: flex;
  16. flex-flow: column nowrap;
  17. justify-content: start;
  18. }
  19. body button {
  20. margin-bottom: 10px;
  21. border: 1px solid orangered;
  22. background-color: wheat;
  23. width: 280px;
  24. }
  25. body button:hover {
  26. border: 1px solid orange;
  27. background-color: papayawhip;
  28. cursor: pointer;
  29. }
  30. </style>
  31. </head>
  32. <body>
  33. <button type="button">1. load()请求数据</button>
  34. <button type="button">2. $.get()请求数据</button>
  35. <button type="button">3. $.post()请求数据</button>
  36. <button type="button">4. $.getJSON()请求JSON数据</button>
  37. <button type="button">5. $.ajax()请求数据</button>
  38. <button type="button">6. $.ajax()-jsonp-跨域请求数据1</button>
  39. <button type="button">7. $.ajax()-jsonp-跨域请求数据2</button>
  40. </body>
  41. <script>
  42. var cl = console.log.bind(console);
  43. // 1. load(): 加载HTML片段, 即把其他HTML页面文件加载进来, 加载方式: 异步, GET方式加载
  44. $("button:first-of-type").click(function () {
  45. alert(134);
  46. cl(this);
  47. // after()函数: 在当前元素后面增加一个指定元素(作为其兄弟元素),
  48. // 然后获取当前元素的下一个兄弟元素, 在其中加载nav.html文件
  49. $(this).after("<div>").next("div").load("nav.html");
  50. });
  51. // 2. $.get(url, data, callback): 以get的方式从服务器获取资源/数据
  52. $("button:nth-of-type(2)").click(function (event) {
  53. $.get(
  54. "users.php",
  55. // 因为是get请求, 所以, 可以在user.php后面增加?id=2, 也可以给第二个参数入参对象字面量来传递get请求参数
  56. { id: 2 },
  57. function (data) {
  58. // cl(data);
  59. // 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
  60. $(event.target).after("<div>").next().html(data);
  61. }
  62. );
  63. });
  64. // 3. $.post(url, data, callback): 以post的方式从服务器获取资源/数据, 使用方法跟get很类似
  65. $("button:nth-of-type(3)").click(function (event) {
  66. $.post("users.php", { id: 2 }, function (data) {
  67. // cl(data);
  68. // 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
  69. $(event.target).after("<div>").next().html(data);
  70. });
  71. });
  72. // 4. $.getJSON(url, data, callback): 接口大多返回的是JSON
  73. $("button:nth-of-type(4)").click(function (event) {
  74. $.getJSON("users.php?id=2", function (data) {
  75. /* 跟普通的get请求不同的点: getJSON()方法会自动把返回的字符串转换为JSON对象,
  76. 再传入回调函数中, 即, 自动执行var data = JSON.parse(res)语句, 得到的
  77. data是一个JS对象数据. */
  78. // cl(data);
  79. var res = data.id + ":" + data.name + ", " + data.age + "岁";
  80. // 在当前元素后面新增一个div元素, 并把data作为其innerHTML属性值.
  81. $(event.target).after("<div>").next().html(res);
  82. });
  83. });
  84. // 5. $ajax(): 能实现上面2到4的方法, 实际上掌握这个方法即可.
  85. /* 五个常用对象字面量参数:
  86. type: 请求类型, 即: GET, POST
  87. url: 请求的url
  88. data: 发送的数据, 若是GET请求, 数据可以放到url上, 而POST请求必须放到data这里
  89. dataType: 期望服务器返回/相应的数据类型(大部分场景可以自己判断)
  90. success: function(data) {// 回调函数...入参的data是服务器返回的数据}
  91. */
  92. // 实例:
  93. $("button:nth-of-type(5)").click(function (event) {
  94. // 发送POST请求
  95. $.ajax({
  96. type: "POST",
  97. url: "users.php",
  98. data: { id: 2 },
  99. dataType: "json",
  100. success: function (data) {
  101. alert("success");
  102. cl(data);
  103. },
  104. });
  105. });
  106. // 6. $.ajax()-jsonp-1: 发送跨域请求
  107. /* "http://php.edu/0522/test2.php?jsonp=handle&id=2" */
  108. $("button:nth-of-type(6)").click(function (event) {
  109. // 发送POST请求
  110. $.ajax({
  111. type: "GET",
  112. // jsonp参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符,
  113. // 请求成功后, 会用success(data)函数来填充?占位符.
  114. url: "http://php.edu/0522/test2.php?jsonp=?&id=2",
  115. // 返回的数据类型是jsonp
  116. dataType: "jsonp",
  117. success: function (data) {
  118. // test2.php返回的是一个JSON字符串
  119. cl(data);
  120. // 转成js对象
  121. var res = JSON.parse(data);
  122. // 输出到页面中, 略
  123. },
  124. });
  125. });
  126. // 7. $.ajax()-jsonp-1: 发送跨域请求
  127. /* "http://php.edu/0522/test2.php?jsonp=handle&id=2" */
  128. $("button:nth-of-type(7)").click(function (event) {
  129. // 发送POST请求
  130. $.ajax({
  131. type: "GET",
  132. // jsonp参数指定的是当前脚本中的一个回调函数, 一般不写死, 用?做占位符,
  133. // 请求成功后, 会用success(data)函数来填充?占位符.
  134. url: "http://php.edu/0522/test2.php?jsonp=?&id=2",
  135. // 返回的数据类型是jsonp
  136. dataType: "jsonp",
  137. // 不想用success(data)来填充?占位的话, 可以用jsonpCallback来指定一个函数, 来填充?占位
  138. jsonpCallback: 'handle',
  139. });
  140. });
  141. function handle(data) {
  142. // test2.php返回的是一个JSON字符串
  143. cl(data);
  144. // 转成js对象
  145. var res = JSON.parse(data);
  146. // 输出到页面中, 略
  147. }
  148. </script>
  149. </html>

2. 使用jQuery操作ajax实现无刷新分页小实战

实现思路:

  • 把创建分页元素字符串的脚本封装起来, 根据传入的”当前页”, “总记录数”, “显示的页码个数”来创建分页元素字符串. 再传入一个回调函数作为页码点击事件的处理脚本.
  • 处理脚本主要完成:
      1. 根据”当前页”和”总记录数”两个参数查询分页数据和记录总数
      1. 拼接查询结果字符串, 作为表格的表体内容, 并插入表格的表体(<tbody>元素)
      1. 移除页面上已有的.pagination元素, 再插入新创建的分页元素.

封装生成分页元素的pagination/pagination.js

  1. var Pagination = {
  2. // 第一页
  3. start: 1,
  4. // 一页可以容纳的记录数
  5. pageSize: 3,
  6. // 显示的页码个数
  7. pageNumSize: 5,
  8. // 显示的页码列表
  9. pageNumList: [],
  10. // 总页数
  11. pageCount: 0,
  12. // 页码左右偏移量
  13. pageNumOffset: 0,
  14. // 当前页码
  15. currentPage: 1,
  16. // 总记录数
  17. rowCount: 0,
  18. // 查询回调
  19. search: "",
  20. getPageInfo: function (pageObj = {}, search = "") {
  21. // 初始化各种属性
  22. // this.currentPage: currentPage;
  23. // this.rowCount = rowCount;
  24. // this.pageSize = pageSize;
  25. // this.pageNumSize = pageNumSize;
  26. $.extend(this, pageObj);
  27. this.pageNumOffset = (this.pageNumSize - 1) / 2;
  28. this.pageCount = Math.ceil(parseFloat(this.rowCount) / this.pageSize);
  29. if (this.pageCount <= 1) {
  30. return "";
  31. }
  32. /* 当传入的当前页码效于最小页码时,初始化为1;大于最大页码时,初始化为最大页码 */
  33. this.currentPage =
  34. this.currentPage < 1
  35. ? 1
  36. : this.currentPage > this.pageCount
  37. ? this.pageCount
  38. : this.currentPage;
  39. // 回调
  40. if (search != null) this.search = search;
  41. // 计算显示的页码列表
  42. this.getPageNumList();
  43. // 生成分页数据
  44. return this.createPageInfo();
  45. },
  46. getPageNumList: function () {
  47. this.pageNumList = [];
  48. // 如果要显示的页码数量>=总页码数量,则显示所有页码。
  49. if (this.pageCount <= this.pageNumSize) {
  50. for (var i = 1; i <= this.pageCount; i++) {
  51. this.pageNumList.push(i);
  52. }
  53. return;
  54. }
  55. // 起始页码,取“当前页码-页码偏移量”和起始页码的最大值。
  56. pageNumStart =
  57. this.currentPage - this.pageNumOffset < this.start
  58. ? this.start
  59. : this.currentPage - this.pageNumOffset;
  60. // 结束页码,取“当前页码+页码偏移量”和总页码数的最小值。
  61. pageNumEnd =
  62. pageNumStart + this.pageNumSize - 1 > this.pageCount
  63. ? this.pageCount
  64. : pageNumStart + this.pageNumSize - 1;
  65. // 若结束页码等于总页码,则再计算一次起始页码(避免当前页到结束页码的差值小于页码偏移量的情况)
  66. if (pageNumEnd === this.pageCount) {
  67. // 起始页码,取“最大页码-要显示的页码数量+1”和起始页码的最大值。
  68. pageNumStart =
  69. this.pageCount - this.pageNumSize + 1 < this.start
  70. ? this.start
  71. : this.pageCount - this.pageNumSize + 1;
  72. }
  73. // 生成要显示的页码数组
  74. for (var i = pageNumStart; i <= pageNumEnd; i++) {
  75. this.pageNumList.push(i);
  76. }
  77. },
  78. createPageInfo: function () {
  79. var pageHtml = '<div class="pagination">';
  80. pageHtml += '<link rel="stylesheet" href="pagination/pagination.css">';
  81. // 首页
  82. var tmpHtml =
  83. this.currentPage === 1
  84. ? '<span class="pageNum disabled">首页</span>'
  85. : '<span class="pageNum" onclick="' +
  86. this.search +
  87. "(1, " +
  88. this.pageNumSize +
  89. ')">首页</span>';
  90. pageHtml += tmpHtml;
  91. // 上一页
  92. tmpHtml =
  93. this.currentPage === 1
  94. ? '<span class="pageNum disabled">上一页</span>'
  95. : '<span class="pageNum" onclick="' +
  96. this.search +
  97. "("+(this.currentPage - 1)+", " +
  98. this.pageNumSize +
  99. ')">上一页</span>';
  100. pageHtml += tmpHtml;
  101. // 间隔符
  102. tmpHtml = this.pageNumList[0] >= 2 ? "..." : "";
  103. pageHtml += tmpHtml;
  104. console.log(this.pageNumList.length);
  105. // 显示的页码
  106. this.pageNumList.forEach((pageNum) => {
  107. tmpHtml =
  108. pageNum == this.currentPage
  109. ? '<span class="pageNum active">' + pageNum + "</span>"
  110. : '<span class="pageNum" data-pageNum="' +
  111. pageNum +
  112. '" onclick="' +
  113. this.search +
  114. "(" +
  115. pageNum +
  116. ", " +
  117. this.pageNumSize +
  118. ')">' +
  119. pageNum +
  120. "</span>";
  121. pageHtml += tmpHtml;
  122. });
  123. // 间隔符
  124. tmpHtml = this.pageNumList[this.pageNumSize - 1] <= this.pageCount - 1 ? "..." : "";
  125. pageHtml += tmpHtml;
  126. // 下一页
  127. tmpHtml =
  128. this.currentPage >= this.pageCount
  129. ? '<span class="pageNum disabled">下一页</span>'
  130. : '<span class="pageNum" onclick="' +
  131. this.search +
  132. "(" +
  133. (this.currentPage + 1) +
  134. ", " +
  135. this.pageNumSize +
  136. ')">下一页</span>';
  137. pageHtml += tmpHtml;
  138. // 末页
  139. tmpHtml =
  140. this.currentPage >= this.pageCount
  141. ? '<span class="pageNum disabled">末页</span>'
  142. : '<span class="pageNum" onclick="' +
  143. this.search +
  144. "(" +
  145. this.pageCount +
  146. ", " +
  147. this.pageNumSize +
  148. ')">末页</span>';
  149. pageHtml += tmpHtml;
  150. pageHtml += "</div>";
  151. return pageHtml;
  152. },
  153. };

前端显示查询分页结果页面player.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>球员列表</title>
  7. <!-- CDN方式引用, 即内容分发方式 -->
  8. <!-- BootCDN或者又拍云的CDN的速度都可以 -->
  9. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
  10. <!-- 本地引用 -->
  11. <script src="pagination/pagination.js"></script>
  12. <style>
  13. table {
  14. border: 0;
  15. min-width: 800px;
  16. margin: 0 auto 30px;
  17. border-spacing: 0px;
  18. }
  19. table caption {
  20. font-size: 1.5rem;
  21. margin-bottom: 20px;
  22. }
  23. table thead tr {
  24. background-color: lightskyblue;
  25. }
  26. table tbody tr:hover {
  27. background-color: lightcyan;
  28. }
  29. table tr td,
  30. th {
  31. border: 1px solid #ccc;
  32. padding: 0 10px;
  33. height: 30px;
  34. color: #666;
  35. }
  36. </style>
  37. </head>
  38. <body>
  39. <table>
  40. <caption>
  41. 球员列表
  42. </caption>
  43. <thead>
  44. <tr>
  45. <th>ID</th>
  46. <th>姓名</th>
  47. <th>球队</th>
  48. <th>身高(cm)</th>
  49. <th>体重(kg)</th>
  50. <th>位置</th>
  51. <th>创建时间</th>
  52. <th>修改时间</th>
  53. </tr>
  54. </thead>
  55. <tbody>
  56. <!-- 将插入球员列表 -->
  57. </tbody>
  58. </table>
  59. </body>
  60. <script>
  61. // 获取球员分页数据
  62. function playerList(pageNum = 1, pageSize = 5) {
  63. $.ajax({
  64. type: "POST",
  65. url: "player.php",
  66. data: {
  67. pageNum: pageNum,
  68. pagSize: pageSize,
  69. },
  70. dataType: "json",
  71. success: function (res) {
  72. // 查询成功
  73. if (res.status == "1") {
  74. // 渲染分页球员数据
  75. var dataStr = renderData(res.data.pageData, res.data.count);
  76. $("tbody").html(dataStr);
  77. // 获取分页元素字符串
  78. var paginate = Pagination.getPageInfo(
  79. {
  80. currentPage: pageNum,
  81. pageSize: pageSize,
  82. // pageNumSize: pageSize,
  83. rowCount: parseInt(res.data.count),
  84. },
  85. "playerList"
  86. );
  87. // 若页面中已存在分页元素, 则删除之
  88. var $pagination = $('.pagination');
  89. if($pagination.length > 0)
  90. $pagination.parent().get(0).removeChild($pagination.get(0));
  91. // 转换并插入最新生成的分页元素
  92. $("body").append($(paginate));
  93. }
  94. },
  95. });
  96. }
  97. // 渲染数据
  98. function renderData(pageData, count) {
  99. // var players = res.data.pageData;
  100. // var count = res.data.count;
  101. if (pageData.length > 0) {
  102. var playerStr = "";
  103. pageData.forEach((element) => {
  104. playerStr += "<tr>";
  105. playerStr += "<td>" + element.id + "</td>";
  106. playerStr += "<td>" + element.name + "</td>";
  107. playerStr += "<td>" + element.team + "</td>";
  108. playerStr += "<td>" + element.height + "</td>";
  109. playerStr += "<td>" + element.weight + "</td>";
  110. playerStr += "<td>" + element.position + "</td>";
  111. playerStr += "<td>" + element.create_time + "</td>";
  112. playerStr += "<td>" + element.update_time + "</td>";
  113. playerStr += "</tr>";
  114. });
  115. } else {
  116. return '<tr><td colspan="8">啥也没查到...</td></tr>';
  117. }
  118. return playerStr;
  119. }
  120. // run~~!!!
  121. playerList();
  122. </script>
  123. </html>

运行效果图:

3. 学习心得

  • jQuery操作ajax, 简化了代码, 但是也隐藏了很多细节, 需要对比原生ajax请求来加深记忆.
  • 无刷新分页的小实战, 是强迫自己以面向对象的思想, 封装分页拼装细节, 但是感觉还是把过程封装而已, 可复用性不强, 还需要加强自己的抽象总结能力.
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议