欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

选择卡示例购物车练习(逻辑有点跟不上,取消选择框重新计算价格没有写出来),又练习了幻灯片的制作

程序员文章站 2022-04-17 19:00:46
...

选择卡示例
重新复习了.filter返回条件的第一个元素(数组型)
重新复习了.find 返回符合条件的第一个元素
重新复习了.classList.remove 删除class元素
重新复习了.classList.add 增加元素
重新复习了.currentTarget 绑定者
重新复习了.target 触发者
重新复习了.Array.from 类数组转换
重新复习了[…类数组] 类数组转换
重新复习了.dataset.index 自定义元素

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>实战选择卡</title>
  7. </head>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. div {
  15. border: green 1px solid;
  16. height: 20rem;
  17. display: grid;
  18. grid-template-rows: repeat(4, 1fr);
  19. }
  20. .head .heada {
  21. display: none;
  22. }
  23. .head ul:first-of-type li {
  24. clear: none;
  25. float: left;
  26. color: orange;
  27. padding: 2px;
  28. margin: 2px;
  29. }
  30. .head .heada.index {
  31. display: block;
  32. }
  33. li {
  34. list-style: none;
  35. }
  36. body {
  37. display: grid;
  38. }
  39. .gaoliang {
  40. background-color: green;
  41. display: block;
  42. }
  43. a {
  44. color: #fff;
  45. }
  46. div ul.heada.gaoliang {
  47. display: block;
  48. }
  49. </style>
  50. <body>
  51. <div class="head">
  52. <ul onclick="show()">
  53. <li data-index="1" class="gaoliang">测试1</li>
  54. <li data-index="2">测试2</li>
  55. <li data-index="3">测试3</li>
  56. </ul>
  57. <ul class="heada index gaoliang" data-index="1">
  58. <li><a href="#">选择卡1</a></li>
  59. <li><a href="#">选择卡1</a></li>
  60. <li><a href="#">选择卡1</a></li>
  61. </ul>
  62. <ul class="heada" data-index="2">
  63. <li><a href="#">选择卡2</a></li>
  64. <li><a href="#">选择卡2</a></li>
  65. <li><a href="#">选择卡2</a></li>
  66. </ul>
  67. <ul class="heada" data-index="3">
  68. <li><a href="#">选择卡3</a></li>
  69. <li><a href="#">选择卡3</a></li>
  70. <li><a href="#">选择卡3</a></li>
  71. </ul>
  72. </div>
  73. <script>
  74. function show() {
  75. console.log(event);
  76. // 当前事件绑定到了父级
  77. console.log(event.currentTarget);
  78. // 查看当前事件触发者
  79. console.log(event.target);
  80. const ul = event.currentTarget;
  81. const li = event.target;
  82. // 当点击某个标签时,其他标签取消高亮,当前标签变为高亮
  83. // 先拿到当前ul绑定者的子级,触发者,
  84. console.log(ul.children);
  85. // 当前触发者是类数组,需要处理成数组
  86. console.log([...ul.children]);
  87. // 意思是拿到ul的子元素, 循环找到所有li标签, 删除所有的class属性值为gaoliang的
  88. [...ul.children].forEach(li => li.classList.remove("gaoliang"));
  89. // 这个地方意思就是触发者追加一个class属性值为gaoliang
  90. li.classList.add("gaoliang");
  91. /////////////////拿内容部分/////////////////
  92. const uls = document.querySelectorAll(".heada");
  93. console.log(uls);
  94. const ulsa = Array.from(uls);
  95. // 老实说不需要转换,都是数组形式,我已经转换完了,看了看
  96. uls.forEach(li => li.classList.remove("gaoliang"));
  97. // 然后转换成数组,之前我已经转换成ulsa了
  98. // filter过滤器过滤满足条件的data-inedx的数据
  99. // 把filter换成find拿到的是这个html节点
  100. const content = [...ulsa].find(function (ul) {
  101. return ul.dataset.index === li.dataset.index;
  102. });
  103. console.log(content);
  104. // contents返回的值就是一个数组,一个成员的数组,换一个方法来
  105. content.classList.add("gaoliang");
  106. }
  107. </script>
  108. </body>
  109. </html>

购物车跟老师写了一遍,加强了map,foreach两种遍历循环的认识,以及reduce叠加器认识,
虽然加强认识,但是总是感觉乱乱的,看到map一般是函数的返回上,但是foreach一般是填充到页面上.reduce累加器一般是计算结果,map或者把数组里面的索引拿出来单独用,还得强加联系
代码部分:

  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. <style>
  9. .box {
  10. width: 22em;
  11. height: 2em;
  12. }
  13. .list > li {
  14. height: 1.6em;
  15. background-color: #efefef;
  16. display: grid;
  17. grid-template-columns: repeat(5, 3em);
  18. gap: 1em;
  19. place-items: center right;
  20. border-bottom: 1px solid #ccc;
  21. }
  22. .list > li:first-of-type {
  23. background-color: lightseagreen;
  24. color: white;
  25. }
  26. .list > li:hover:not(:first-of-type) {
  27. cursor: pointer;
  28. background-color: lightcyan;
  29. }
  30. .list > li input[type="number"] {
  31. width: 3em;
  32. border: none;
  33. outline: none;
  34. text-align: center;
  35. font-size: 1em;
  36. background-color: transparent;
  37. }
  38. .list > li:last-of-type span.total-num,
  39. .list > li:last-of-type span.total-amount {
  40. grid-column: span 2;
  41. place-self: center right;
  42. color: lightseagreen;
  43. }
  44. .account {
  45. float: right;
  46. background-color: lightseagreen;
  47. color: white;
  48. border: none;
  49. outline: none;
  50. width: 4.5em;
  51. height: 1.8em;
  52. }
  53. .account:hover {
  54. background-color: coral;
  55. cursor: pointer;
  56. }
  57. </style>
  58. </head>
  59. <body>
  60. <div class="box">
  61. <div class="selectAll">
  62. <input type="checkbox" class="check-all" name="check-all" onchange="checkAll()" checked />
  63. <label for="check-all">全选</label>
  64. </div>
  65. <ul class="list">
  66. <li><span>选择</span><span>品名</span><span>数量</span><span>单价</span><span>金额</span></li>
  67. <li>
  68. <input type="checkbox" onchange="checkItems()" checked />
  69. <span class="content">手机</span>
  70. <input type="number" value="1" min="1" class="num" />
  71. <span class="price">100</span>
  72. <span class="amount">0</span>
  73. </li>
  74. <li>
  75. <input type="checkbox" onchange="checkItems()" checked />
  76. <span class="content">电脑</span>
  77. <input type="number" value="2" min="1" class="num" />
  78. <span class="price">200</span><span class="amount">0</span>
  79. </li>
  80. <li>
  81. <input type="checkbox" onchange="checkItems()" checked />
  82. <span class="content">相机</span>
  83. <input type="number" value="3" min="1" class="num" />
  84. <span class="price">300</span>
  85. <span class="amount">0</span>
  86. </li>
  87. <li>
  88. <span>总计:</span>
  89. <span class="total-num">0</span>
  90. <span class="total-amount">0</span>
  91. </li>
  92. </ul>
  93. <button class="account">结算</button>
  94. </div>
  95. </body>
  96. <script>
  97. function checkAll() {
  98. // 获取全选框的点击状态 返回true跟false
  99. let ad = event.target.checked;
  100. console.log(ad);
  101. // 获取下面所有的全选框状态,根据主全选框动态设置子全选框
  102. let zys = document.querySelectorAll(".list li input[type=checkbox]");
  103. console.log(zys);
  104. // 用forEach循环拿到数组zys的数组值,然后让ad的值全部给数组的值
  105. zys.forEach(function (zhi) {
  106. return (zhi.checked = ad);
  107. });
  108. }
  109. function checkItems() {
  110. let zys = document.querySelectorAll(".list li input[type=checkbox]");
  111. console.log(zys);
  112. // every判断
  113. let quanxuan = [...zys].every(function (zhi) {
  114. // 判断zhi.checked全部返回true则返回true 如果不是则返回fales
  115. return zhi.checked === true;
  116. });
  117. // 把每个商品every返回的状态,给全选按钮
  118. document.querySelector(".check-all").checked = quanxuan;
  119. }
  120. //////////////商品自动计算//////////////////////
  121. const nums = document.querySelectorAll(".num");
  122. console.log(nums);
  123. console.log([...nums]);
  124. // 购物车所有的数据计算依据是:基于商品的"数量"的变化
  125. function zongshu(numArr) {
  126. // acc是累加器,aur是当前数组的每一个值
  127. return numArr.reduce(function (acc, cur) {
  128. return acc + cur;
  129. });
  130. }
  131. //////////////计算每个商品的总额///////////////
  132. // 这里的函数 里面的两个值,都是一个数组,nuarr是数量,pricearr是单价
  133. function getAmount(numArr, priceArr) {
  134. // 这里那numarr当数组处理, map是数组的值 index是键 而pricearr对应了map里面值的键 所以map的键=pricearr的键
  135. return numArr.map((num, index) => num * priceArr[index]);
  136. }
  137. ///////////计算总金额//////////////
  138. function getTotalAmount(amountArr) {
  139. return amountArr.reduce((acc, cur) => acc + cur);
  140. }
  141. // 自动计算
  142. function autoCalculate() {
  143. // 数量数组 从class num中拿到数量,然后用map返回数组
  144. const numArr = [...nums].map(function (num) {
  145. // 直接从value里面拿的值
  146. return parseInt(num.value);
  147. });
  148. //单价数组 单价数组保存在class=price中
  149. const prices = document.querySelectorAll(".price");
  150. // 处理单价 处理成数组//为什么使用textcontent 因为他在html中
  151. const pricearr = [...prices].map(num => parseInt(num.textContent));
  152. //金额数组
  153. const amountArr = getAmount(numArr, pricearr);
  154. console.log(amountArr);
  155. // 总数量
  156. document.querySelector(".total-num").textContent = zongshu(numArr);
  157. // 金额
  158. document.querySelectorAll(".amount").forEach((amount, index) => (amount.textContent = amountArr[index]));
  159. // 总金额
  160. document.querySelector(".total-amount").textContent = getTotalAmount(amountArr);
  161. }
  162. console.log(autoCalculate());
  163. // 当购物车加载时触发
  164. window.onload = autoCalculate;
  165. //当数量更新时,触发自动计算
  166. nums.forEach(num => (num.onchange = autoCalculate));
  167. </script>
  168. </html>

幻灯片部分,重新学习了onclick点击事件,已经定时器派发事件的使用,并且对函数的执行有了更加深入的了解,以及自定义dataset.index的深入了解

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>Document</title>
  7. <head>
  8. <meta charset="UTF-8" />
  9. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  11. <title>实战4: 轮播图</title>
  12. <style>
  13. /* ! 3. 轮播图 */
  14. .slider {
  15. max-width: 750px;
  16. min-width: 320px;
  17. margin: auto;
  18. padding: 0 10px;
  19. }
  20. .slider .imgs {
  21. /* 图片容器必须要有高度,否则下面图片不能正常显示 */
  22. height: 150px;
  23. }
  24. .slider .imgs img {
  25. /* 图片完全充满父级空间显示 */
  26. height: 100%;
  27. width: 100%;
  28. /* 图片带有圆角 */
  29. border-radius: 10px;
  30. /* 默认图片全部隐藏,只有有active的图片才显示 */
  31. display: none;
  32. }
  33. /* 默认显示第一张 */
  34. .slider .imgs img.active {
  35. display: block;
  36. }
  37. /* 轮播图按钮组 */
  38. .slider .btns {
  39. /* 按钮水平一排显示,用flex,且水平居中 */
  40. display: flex;
  41. place-content: center;
  42. }
  43. .slider .btns span {
  44. /* 按钮宽高相同,确定显示成一个正圆 */
  45. width: 8px;
  46. height: 8px;
  47. /* 加上红色背景和数字是为了布局时可以看到,一会更去掉 */
  48. background-color: rgba(255, 255, 255, 0.4);
  49. /* 50%可确保显示为正圆 */
  50. border-radius: 50%;
  51. /* 按钮上外边距负值,可将它上移,可移动到图片中下方 */
  52. margin: -12px 3px 5px;
  53. }
  54. .slider .btns span.active {
  55. background-color: #fff;
  56. }
  57. </style>
  58. </head>
  59. <body>
  60. <div class="slider">
  61. <!-- 图片容器 -->
  62. <div class="imgs">
  63. <!-- 轮播图默认从第一张开始显示 -->
  64. <a href=""><img src="./images/banner1.jpg" alt="" data-index="1" class="active" /></a>
  65. <a href=""><img src="./images/banner2.jpg" alt="" data-index="2" /></a>
  66. <a href=""><img src="./images/banner3.png" alt="" data-index="3" /></a>
  67. </div>
  68. <!-- 切换按钮数量与图片数量必须一致 -->
  69. <div class="btns">
  70. <span data-index="1" class="active" onclick="setActive()"></span>
  71. <span data-index="2" onclick="setActive()"></span>
  72. <span data-index="3" onclick="setActive()"></span>
  73. </div>
  74. </div>
  75. </body>
  76. <script>
  77. //获取全部图片及图片按钮
  78. let imgs = document.querySelectorAll(".slider .imgs img")
  79. console.log(imgs)
  80. let spans = document.querySelectorAll(".slider .btns span")
  81. console.log(spans)
  82. // 设置激活按钮
  83. function setActive() {
  84. imgs.forEach(i => i.classList.remove("active"))
  85. spans.forEach(i => i.classList.remove("active"))
  86. // 触发者增加class active
  87. event.target.classList.add("active");
  88. // 图片已经设置了一个foreach循环删除active,下面遍历imgs,如果imgdataset.index===点击的spans触发者是同一个dataset.index
  89. // 则img class增加active
  90. imgs.forEach(function(img) {
  91. if (img.dataset.index === event.target.dataset.index) {
  92. img.classList.add("active")
  93. }
  94. });
  95. }
  96. // 设置定时器
  97. setInterval(
  98. function(arr) {
  99. // 声明一个i,删除数组里面的第一项
  100. let i = arr.shift(); ///括号 括号 不是中括号
  101. // 派发事件i等于btns里面的索引,派发一个click点击事件
  102. spans[i].dispatchEvent(new Event("click"));
  103. // push尾部塞入 塞入是push() 括号 括号 不是中括号
  104. arr.push(i);
  105. },
  106. 2000,
  107. Object.keys(spans)
  108. );
  109. </script>
  110. </html>