博客列表 >JS实战练习:选项卡、在线相册、轮播图、购物车

JS实战练习:选项卡、在线相册、轮播图、购物车

初见
初见原创
2021年10月02日 21:26:07590浏览

JS实战练习及部分知识回顾

选项卡 (css部分省略)

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>选项卡</title>
  8. <link rel="stylesheet" href="css/css.css" />
  9. </head>
  10. <body>
  11. <!-- 选项卡 -->
  12. <div class="tabs">
  13. <!-- 导航部分-->
  14. <ul class="tab" onmouseover="show(event)">
  15. <!-- onclick 点击 onmouseover鼠标滑动 -->
  16. <li class="active" data-index="1">热点</li>
  17. <li data-index="2">推荐</li>
  18. <li data-index="3">最新</li>
  19. </ul>
  20. <!-- 对应的详情 -->
  21. <ul class="item active" data-index="1">
  22. <li><a href="">最新的热门新闻就是焦点新闻1</a></li>
  23. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  24. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  25. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  26. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  27. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  28. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  29. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  30. </ul>
  31. <ul class="item" data-index="2">
  32. <li><a href="">最新的热门新闻就是焦点新闻2</a></li>
  33. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  34. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  35. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  36. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  37. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  38. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  39. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  40. </ul>
  41. <ul class="item" data-index="3">
  42. <li><a href="">最新的热门新闻就是焦点新闻3</a></li>
  43. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  44. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  45. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  46. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  47. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  48. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  49. <li><a href="">最新的热门新闻就是焦点新闻</a></li>
  50. </ul>
  51. </div>
  52. <script>
  53. // 选项卡js
  54. // 知识点 数组过滤器 filter()
  55. // const arr = [2, 5, 2, 10, 8, 50, 3, 6, 90, 7, 1];
  56. // const res = [];
  57. //取大于等于5的数据,传统方式
  58. // for (let i = 0; i < arr.length; i++) {
  59. // if (arr[i] >= 5) {
  60. // res.push(arr[i]);
  61. // }
  62. // }
  63. // console.log(res);
  64. // filter 返回判断结果为true的函数
  65. // console.log(arr.filter(item => item >= 5));
  66. function show(ev) {
  67. // console.log(ev.currentTarget);
  68. // console.log(ev.target);
  69. const ul = ev.currentTarget;
  70. const li = ev.target;
  71. // 1、控制顶部导航的显示
  72. //添加之前,去掉高亮的导航
  73. //console.log([...ul.children]); // 查看发现它是一个元素结合(类数组) 加上...转为数组
  74. //遍历这个数组即可forEach
  75. [...ul.children].forEach(li => li.classList.remove("active"));
  76. li.classList.add("active");
  77. //2、根据顶部导航的显示,显示对应的内容
  78. const uls = document.querySelectorAll(".item");
  79. uls.forEach(li => li.classList.remove("active"));
  80. //判断依据 data-index 对应相等
  81. // let a = [...uls].filter(ul => ul.dataset.index === li.dataset.index)[0];
  82. // console.log(a.classList.add("active"));
  83. [...uls]
  84. .filter(ul => ul.dataset.index === li.dataset.index)[0]
  85. .classList.add("active");
  86. }
  87. </script>
  88. </body>
  89. </html>

在线相册 (忽略css)

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>在线相册</title>
  8. <link rel="stylesheet" href="style.css" />
  9. </head>
  10. <body>
  11. <ul class="container">
  12. <!-- 所有相片 js动态创建 -->
  13. </ul>
  14. <script>
  15. //array.reduce(前一个成员,当前成员) 最后一个参数是结果的初值 数组的归并函数
  16. // let a = [1, 2, 3, 4, 5].reduce(function (prev, curr) {
  17. // console.log(prev, curr);
  18. // return prev + curr;
  19. // });
  20. // let a = [1, 2, 3, 4, 5].reduce((prev, curr) => prev + curr);
  21. // console.log(a);
  22. // 1、动态生成图片
  23. const ul = document.querySelector(".container");
  24. //console.log(ul);
  25. const imgs = [
  26. "images/img_1.jpg",
  27. "images/img_2.jpg",
  28. "images/img_3.jpg",
  29. "images/img_4.jpg",
  30. "images/img_5.jpg",
  31. "images/img_6.jpg",
  32. "images/img_7.jpg",
  33. "images/img_8.jpg",
  34. ];
  35. //load()当页面加载成功立即执行
  36. window.onload = showImgs;
  37. //声明showImgs
  38. function showImgs() {
  39. let res = imgs.reduce((prev, curr) => {
  40. let tpl = `
  41. <li>
  42. <img src="${curr}" />
  43. <div>
  44. <button onclick="prev(this.parentNode.parentNode)">向前</button>
  45. <button onclick="next(this.parentNode.parentNode)">向后</button>
  46. <button onclick="del(this.parentNode.parentNode)">删除</button>
  47. </div>
  48. </li>
  49. `;
  50. return prev + tpl;
  51. }, "");
  52. //console.log(res);
  53. ul.insertAdjacentHTML("afterbegin", res);
  54. }
  55. //删除
  56. function del(ele) {
  57. return confirm("是否删除?") ? ele.remove() : false;
  58. }
  59. //向前
  60. function prev(ele) {
  61. if (ele.previousElementSibling === null) {
  62. alert("已经是第一张");
  63. return false;
  64. }
  65. let prevNode = ele.previousElementSibling;
  66. ul.insertBefore(ele, prevNode);
  67. //console.log(prevNode);
  68. }
  69. //向后
  70. function next(ele) {
  71. if (ele.nextElementSibling === null) {
  72. alert("已经是最后一张");
  73. return false;
  74. }
  75. let nextNode = ele.nextElementSibling;
  76. ul.insertBefore(nextNode, ele);
  77. //console.log(prevNode);
  78. }
  79. </script>
  80. </body>
  81. </html>

轮播图

轮播图

  • html部分
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>轮播图</title>
  8. <link rel="stylesheet" href="style.css" />
  9. </head>
  10. <body>
  11. <!-- 轮播图 -->
  12. <div class="container">
  13. <!-- 图片组 -->
  14. <div class="img-group"></div>
  15. <!-- 和图片对应数量的按钮 -->
  16. <div class="btn-group"></div>
  17. <!-- 向前和向后翻页 -->
  18. <div class="skip">
  19. <!-- javascript:; -->
  20. <a class="prev" href="" onclick="prevImg(event)">&lt;</a>
  21. <a class="next" href="" onclick="nextImg(event)">&gt;</a>
  22. </div>
  23. </div>
  24. <!-- <ul class="list"></ul> -->
  25. <script src="banner.js"></script>
  26. </body>
  27. </html>
  • banner.js
  1. //文档片段
  2. // const ul = document.querySelector(".list");
  3. // // 文档碎片
  4. // const frag = document.createDocumentFragment();
  5. // for (let i = 0; i < 100; i++) {
  6. // const li = document.createElement("li");
  7. // li.textContent = "item" + (i + 1);
  8. // frag.append(li);
  9. // }
  10. // ul.append(frag);
  11. const banner = [
  12. "images/banner_1.jpg",
  13. "images/banner_2.jpg",
  14. "images/banner_3.jpg",
  15. "images/banner_4.jpg",
  16. ];
  17. //图片组
  18. const imgGroup = document.querySelector(".container > .img-group");
  19. //按钮组
  20. const btnGroup = document.querySelector(".container > .btn-group");
  21. // 当页面加载成功时,将所有图片和按钮全部渲染
  22. window.onload = () => {
  23. // 生成所有图片
  24. createImgs(imgGroup, banner.length);
  25. //生成图片对应的按钮
  26. createBtns(btnGroup, banner.length);
  27. };
  28. function createImgs(parent, length) {
  29. const frag = document.createDocumentFragment();
  30. for (let i = 0; i < length; i++) {
  31. const img = document.createElement("img");
  32. //添加索引
  33. img.dataset.index = `${i + 1}`;
  34. if (i === 0) img.classList.add("active");
  35. img.src = banner[i];
  36. frag.append(img);
  37. }
  38. parent.append(frag);
  39. }
  40. function createBtns(parent, length) {
  41. const frag = document.createDocumentFragment();
  42. for (let i = 0; i < length; i++) {
  43. const span = document.createElement("span");
  44. //添加索引
  45. span.dataset.index = `${i + 1}`;
  46. if (i === 0) span.classList.add("active");
  47. span.onclick = showImgs;
  48. frag.append(span);
  49. }
  50. parent.append(frag);
  51. }
  52. function showImgs(ev) {
  53. //获取所有图片和按钮
  54. const imgArr = imgGroup.querySelectorAll("img");
  55. const btnArr = btnGroup.querySelectorAll("span");
  56. console.log(imgArr, btnArr);
  57. //根据图片激活状态,显示对应的图片
  58. btnArr.forEach(btn => btn.classList.remove("active"));
  59. imgArr.forEach(img => img.classList.remove("active"));
  60. ev.target.classList.add("active");
  61. // 添加根据按钮和图片data-index属性的值 匹配上在激活
  62. imgArr.forEach(img => {
  63. if (ev.target.dataset.index === img.dataset.index)
  64. img.classList.add("active");
  65. });
  66. }
  67. //翻页
  68. // 向前
  69. function prevImg(ev) {
  70. ev.preventDefault(); // 禁用a标签的默认跳转行为
  71. //1、当前图片和当前按钮
  72. const currentImg = imgGroup.querySelector("img.active");
  73. const currentBtn = btnGroup.querySelector("span.active");
  74. //2、取消当前图片和当前按钮的激活状态
  75. currentImg.classList.remove("active");
  76. currentBtn.classList.remove("active");
  77. //3、取得当前图片和按钮的前一个兄弟节点
  78. const prevImg = currentImg.previousElementSibling;
  79. const prevBtn = currentBtn.previousElementSibling;
  80. //
  81. //4、如果存在前一个兄弟,就设置它为激活状态
  82. if (prevImg !== null && prevBtn !== null) {
  83. prevBtn.classList.add("active");
  84. prevImg.classList.add("active");
  85. } else {
  86. imgGroup.lastElementChild.classList.add("active");
  87. btnGroup.lastElementChild.classList.add("active");
  88. }
  89. }
  90. // 向后
  91. function nextImg(ev) {
  92. ev.preventDefault(); // 禁用a标签的默认跳转行为
  93. //1、当前图片和当前按钮
  94. const currentImg = imgGroup.querySelector("img.active");
  95. const currentBtn = btnGroup.querySelector("span.active");
  96. //2、取消当前图片和当前按钮的激活状态
  97. currentImg.classList.remove("active");
  98. currentBtn.classList.remove("active");
  99. //3、取得当前图片和按钮的前一个兄弟节点
  100. const nextImg = currentImg.nextElementSibling;
  101. const nextBtn = currentBtn.nextElementSibling;
  102. //
  103. //4、如果存在前一个兄弟,就设置它为激活状态
  104. if (nextImg !== null && nextBtn !== null) {
  105. nextBtn.classList.add("active");
  106. nextImg.classList.add("active");
  107. } else {
  108. imgGroup.firstElementChild.classList.add("active");
  109. btnGroup.firstElementChild.classList.add("active");
  110. }
  111. }
  112. //每2s自送切换到下一个,使用setInterval 执行间歇事件
  113. // setInterval(() => {
  114. // //1、当前图片和当前按钮
  115. // const currentImg = imgGroup.querySelector("img.active");
  116. // const currentBtn = btnGroup.querySelector("span.active");
  117. // //2、取消当前图片和当前按钮的激活状态
  118. // currentImg.classList.remove("active");
  119. // currentBtn.classList.remove("active");
  120. // //3、取得当前图片和按钮的前一个兄弟节点
  121. // const nextImg = currentImg.nextElementSibling;
  122. // const nextBtn = currentBtn.nextElementSibling;
  123. // //
  124. // //4、如果存在前一个兄弟,就设置它为激活状态
  125. // if (nextImg !== null && nextBtn !== null) {
  126. // nextBtn.classList.add("active");
  127. // nextImg.classList.add("active");
  128. // } else {
  129. // imgGroup.firstElementChild.classList.add("active");
  130. // btnGroup.firstElementChild.classList.add("active");
  131. // }
  132. // }, 2000);
  133. //简单写法
  134. //获取翻页到下一页的按钮
  135. const cBtn = document.querySelector(".container > .skip > .next");
  136. //创建一个自定义事件
  137. const myclick = new Event("click");
  138. //间歇性执行自定义事件
  139. setInterval(() => cBtn.dispatchEvent(myclick), 2000);

购物车

购物车

  • html部分
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>购物车</title>
  8. <link rel="stylesheet" href="style.css" />
  9. </head>
  10. <body>
  11. <table>
  12. <caption>
  13. 我的购物车
  14. </caption>
  15. <thead>
  16. <th>
  17. <input type="checkbox" name="checkAll" id="check-all" checked /><label
  18. for="check-all"
  19. >全选</label
  20. >
  21. </th>
  22. <th>图片</th>
  23. <th>品名</th>
  24. <th>单位</th>
  25. <th>单价/元</th>
  26. <th>数量</th>
  27. <th>金额/元</th>
  28. </thead>
  29. <tbody>
  30. <tr>
  31. <td>
  32. <input
  33. type="checkbox"
  34. name="item"
  35. class="item"
  36. value="SN-1020"
  37. checked
  38. />
  39. </td>
  40. <td>
  41. <a href=""><img src="images/p1.png" alt="" /></a>
  42. </td>
  43. <td>JavaScript权威指南(第七版)</td>
  44. <td></td>
  45. <td class="price">100</td>
  46. <td><input type="number" min="1" value="1" /></td>
  47. <td class="amount">0</td>
  48. </tr>
  49. <tr>
  50. <td>
  51. <input
  52. type="checkbox"
  53. name="item"
  54. class="item"
  55. value="SN-1020"
  56. checked
  57. />
  58. </td>
  59. <td>
  60. <a href=""><img src="images/p2.png" alt="" /></a>
  61. </td>
  62. <td>JavaScript高级程序设计(第四版)</td>
  63. <td></td>
  64. <td class="price">129</td>
  65. <td><input type="number" min="1" value="1" /></td>
  66. <td class="amount">0</td>
  67. </tr>
  68. <tr>
  69. <td>
  70. <input
  71. type="checkbox"
  72. name="item"
  73. class="item"
  74. value="SN-1030"
  75. checked
  76. />
  77. </td>
  78. <td>
  79. <a href=""><img src="images/p3.png" alt="" /></a>
  80. </td>
  81. <td>JavaScript忍者秘籍(第二版)</td>
  82. <td></td>
  83. <td class="price">99</td>
  84. <td><input type="number" min="1" value="1" /></td>
  85. <td class="amount">0</td>
  86. </tr>
  87. <tr>
  88. <td>
  89. <input
  90. type="checkbox"
  91. name="item"
  92. class="item"
  93. value="SN-1040"
  94. checked
  95. />
  96. </td>
  97. <td>
  98. <a href=""><img src="images/p4.png" alt="" /></a>
  99. </td>
  100. <td>ThinkPad X1 Carbon 2021</td>
  101. <td></td>
  102. <td class="price">12999</td>
  103. <td><input type="number" min="1" value="1" /></td>
  104. <td class="amount">0</td>
  105. </tr>
  106. <tr>
  107. <td>
  108. <input
  109. type="checkbox"
  110. name="item"
  111. class="item"
  112. value="SN-1050"
  113. checked
  114. />
  115. </td>
  116. <td>
  117. <a href=""><img src="images/p5.png" alt="" /></a>
  118. </td>
  119. <td>MacBook Pro 16 10代i7 16G 512G</td>
  120. <td></td>
  121. <td class="price">23800</td>
  122. <td><input type="number" min="1" value="1" /></td>
  123. <td class="amount">0</td>
  124. </tr>
  125. </tbody>
  126. <tfoot>
  127. <tr>
  128. <td colspan="5">总计:</td>
  129. <td id="sum">0</td>
  130. <td id="total-amount">0</td>
  131. </tr>
  132. </tfoot>
  133. </table>
  134. <div style="width: 90%; margin: 10px auto">
  135. <button style="float: right; width: 100px">结算</button>
  136. </div>
  137. <script src="cart.js"></script>
  138. </body>
  139. </html>
  • 复选框和自动计算数值变化(js)[不完整]
  1. const checkAll = document.querySelector("#check-all");
  2. const checkItems = document.getElementsByName("item");
  3. //全选复选框
  4. checkAll.onchange = ev =>
  5. checkItems.forEach(item => (item.checked = ev.target.checked));
  6. checkItems.forEach(
  7. item =>
  8. (item.onchange = () =>
  9. (checkAll.checked = [...checkItems].every(item => item.checked)))
  10. );
  11. //自动计算 所有的计算都是基于数量的变化
  12. const numInput = document.querySelectorAll('input[type="number"]');
  13. numInput.forEach(function (input) {
  14. input.onchange = autoCalculate;
  15. });
  16. function autoCalculate() {
  17. const numbers = document.querySelectorAll('input[type="number"]');
  18. const numArr = [...numbers].map(function (num) {
  19. return num.value * 1;
  20. });
  21. const prices = document.querySelectorAll("tbody .price");
  22. const priceArr = [...prices].map(function (num) {
  23. return num.textContent * 1;
  24. });
  25. //console.log(priceArr);
  26. //计算金额
  27. const amountArr = [priceArr, numArr].reduce(function (prev, curr) {
  28. return prev.map(function (item, key) {
  29. return item * curr[key];
  30. });
  31. });
  32. //console.log(amountArr);
  33. let tatal = amountArr.reduce(function (prev, curr) {
  34. return prev + curr;
  35. });
  36. let sum = numArr.reduce(function (prev, curr) {
  37. return prev + curr;
  38. });
  39. //渲染
  40. document.querySelectorAll(".amount").forEach(function (item, index) {
  41. item.textContent = amountArr[index];
  42. });
  43. document.querySelector("#total-amount").textContent = tatal;
  44. document.querySelector("#sum").textContent = sum;
  45. }
  46. window.onload = autoCalculate;
  • 改进js
  1. //全选复选框
  2. const checkAll = document.querySelector("#check-all");
  3. const checkItems = document.getElementsByName("item");
  4. //设置一个空数值用来接收checkItems checked的值 为true时为1
  5. let isChecked = [];
  6. checkItems.forEach(item => isChecked.push(item.checked === true ? 1 : 0));
  7. //自动计算 所有的计算都是基于数量的变化
  8. const numInput = document.querySelectorAll('input[type="number"]');
  9. numInput.forEach(function (input) {
  10. input.onchange = autoCalculate;
  11. });
  12. function autoCalculate() {
  13. const numbers = document.querySelectorAll('input[type="number"]');
  14. const numArr = [...numbers].map(function (num) {
  15. return num.value * 1;
  16. });
  17. const sumArr = [numArr, isChecked].reduce(function (prev, curr) {
  18. return prev.map(function (item, key) {
  19. return item * curr[key];
  20. });
  21. });
  22. //console.log(numArr);
  23. const prices = document.querySelectorAll("tbody .price");
  24. const priceArr = [...prices].map(function (num) {
  25. return num.textContent * 1;
  26. });
  27. //console.log(priceArr);
  28. //计算金额
  29. const amountArr = [priceArr, numArr].reduce(function (prev, curr) {
  30. return prev.map(function (item, key) {
  31. return item * curr[key];
  32. });
  33. });
  34. const amountAll = [amountArr, isChecked].reduce(function (prev, curr) {
  35. return prev.map(function (item, key) {
  36. return item * curr[key];
  37. });
  38. });
  39. //console.log(amountArr);
  40. let tatal = amountAll.reduce(function (prev, curr) {
  41. return prev + curr;
  42. });
  43. let sum = sumArr.reduce(function (prev, curr) {
  44. return prev + curr;
  45. });
  46. //渲染
  47. document.querySelectorAll(".amount").forEach(function (item, index) {
  48. item.textContent = amountArr[index];
  49. });
  50. document.querySelector("#total-amount").textContent = tatal;
  51. document.querySelector("#sum").textContent = sum;
  52. }
  53. window.onload = autoCalculate;
  54. //判断全选和设置isChecked变化
  55. checkItems.forEach(item => {
  56. item.onchange = () => {
  57. checkAll.checked = [...checkItems].every(item => item.checked);
  58. autoCheck();
  59. };
  60. });
  61. function autoCheck() {
  62. const chItem = document.getElementsByName("item");
  63. const numCheck = [...chItem].map(function (num) {
  64. return num.checked === true ? 1 : 0;
  65. });
  66. isChecked = numCheck;
  67. autoCalculate();
  68. }
  69. console.log(isChecked);
  70. checkAll.onchange = ev => {
  71. isChecked = [];
  72. checkItems.forEach(item => (item.checked = ev.target.checked));
  73. checkItems.forEach(item => isChecked.push(item.checked === true ? 1 : 0));
  74. if (ev.target.checked) {
  75. autoCalculate();
  76. } else {
  77. document.querySelector("#total-amount").textContent = 0;
  78. document.querySelector("#sum").textContent = 0;
  79. }
  80. };

总结:苦思冥想的做了一个半残的js代码,学艺不精,还需要进一步的改进代码,希望老师和同学多多指教。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议