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

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

卢先生
卢先生原创
2022年01月10日 16:24:09270浏览

选择卡示例
重新复习了.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>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议