博客列表 >js之购物车的实现

js之购物车的实现

时间在渗透
时间在渗透原创
2022年11月15日 05:48:58602浏览

1. HTML代码

  1. <!DOCTYPE html>
  2. <html lang="zh">
  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-sizing:border-box;margin:0;padding:0;}
  10. body{font-size:16px;}
  11. table{margin:15px 0;width:100%;border:1px solid #eee;border-collapse:collapse;text-align:center;}
  12. table caption{padding:10px;border-top:5px solid #f08080;border-right:1px solid #eee;border-left:1px solid #eee;font-size:32px;}
  13. table td,table th{padding:5px 8px;height:30px;border-bottom:1px solid #eee;line-height:30px;}
  14. table tbody tr:hover{background-color:#eee;cursor:pointer;}
  15. table tfoot,table thead{background-color:#fafafa;}
  16. table tbody td[colspan="6"]{background-color:#fafafa;}
  17. input[type=number]{padding:5px 3px;height:30px;border:solid 1px #eaeaea;text-align:center;line-height:30px;}
  18. #app{margin:0 auto;width:960px;}
  19. </style>
  20. </head>
  21. <body>
  22. <div id="app">
  23. <table class="cart">
  24. <caption>购物车</caption>
  25. <thead>
  26. <tr>
  27. <!-- 全选按钮 -->
  28. <td><input type="checkbox" name="" class="check-all" checked/></td>
  29. <td>编号</td>
  30. <td>品名</td>
  31. <td>单位</td>
  32. <td>单价/元</td>
  33. <td>库存</td>
  34. <td>数量</td>
  35. <td>金额(元)</td>
  36. </tr>
  37. </thead>
  38. </table>
  39. </div>
  40. <script type="module">
  41. import Cart from "./module/Cart.js"
  42. const items = [
  43. { id: 286, name: '酸奶', units: '箱', price: 50, stock: 15, num: 1 },
  44. { id: 870, name: '苹果', units: '千克', price: 10, stock: 50, num: 1 },
  45. { id: 633, name: '外套', units: '件', price: 300, stock: 20, num: 1 },
  46. { id: 153, name: '皮鞋', units: '双', price: 400, stock: 10, num: 1 },
  47. { id: 109, name: '手机', units: '台', price: 5000, stock: 20, num: 0 },
  48. ];
  49. const cart = new Cart(items);
  50. //console.log(cart.getTotalMoney())
  51. // console.log(cart.payMoney)
  52. const table = document.querySelector('table');
  53. const tbody = table.createTBody();
  54. items.forEach(function(item, key) {
  55. // 1. 创建商品模板字符串
  56. const tr = `
  57. <tr>
  58. <td><input type="checkbox" name="" class="check-one" checked /></td>
  59. <td>${item.id}</td>
  60. <td>${item.name}</td>
  61. <td>${item.units}</td>
  62. <td>${item.price}</td>
  63. <td class="stock">${cart.stockNum[key]}</td>
  64. <td>
  65. <input type="number" name="num" value="${item.num}" min="0" max="${item.stock}">
  66. </td>
  67. <td class="money">${cart.money[key]}</td>
  68. </tr>
  69. `;
  70. // 2. 将内容填充到tbody
  71. tbody.insertAdjacentHTML('beforeend', tr);
  72. });
  73. const tfoot = table.createTFoot();
  74. // 创建tfoot内容
  75. let tr = `
  76. <tr>
  77. <td rowspan="2" colspan="6">总计:</td>
  78. <td rowspan="2" class="total">${cart.total}</td>
  79. <td>
  80. 优惠: <span class="reduce">${cart.reduce}</span>元
  81. </td>
  82. </tr>
  83. <tr>
  84. <td>
  85. 原价: <span class="total-money" style="color: blue;">${cart.totalMoney}</span>元<br>
  86. 实付: <span class="pay-money" style="color: red;">${cart.payMoney}</span>元
  87. </td>
  88. </tr>
  89. `;
  90. tfoot.insertAdjacentHTML('beforeend', tr);
  91. // 拿到所有的数量控件
  92. const nums = table.querySelectorAll('[type=number]');
  93. nums.forEach(function(num, key) {
  94. num.oninput = function() {
  95. // 1. 计算总数量
  96. items[key].num = num.value * 1;
  97. // if (items[key].num > items[key].stock) {
  98. // alert(没有库存了);
  99. // }
  100. cart.total = cart.getTotal(items);
  101. // 2. 计算每个商品金额
  102. cart.money[key] = num.value * 1 * items[key].price;
  103. // 3. 计算商品总金额
  104. cart.totalMoney = cart.money.reduce(function(acc, cur) {
  105. return acc + cur;
  106. });
  107. // 更新折扣和实付价格
  108. cart.reduce = cart.getReduce(cart.totalMoney);
  109. cart.payMoney = cart.totalMoney - cart.reduce;
  110. //console.log(items[key].stock, num.value);
  111. // 4. 计算库存
  112. cart.stockNum[key] = parseInt(items[key].stock) - parseInt(num.value);
  113. // 4. 将数据渲染到指定元素上
  114. table.querySelector('.total').textContent = cart.total;
  115. table.querySelectorAll('.money')[key].textContent = cart.money[key];
  116. table.querySelector('.total-money').textContent = cart.totalMoney;
  117. table.querySelector('.pay-money').textContent = cart.payMoney;
  118. table.querySelector('.reduce').textContent = cart.reduce;
  119. table.querySelectorAll('.stock')[key].textContent = cart.stockNum[key];
  120. };
  121. });
  122. /**
  123. * 全选事件
  124. */
  125. // 全选选择器
  126. const checkboxAll = table.querySelector('.check-all');
  127. // 除了全选以外的节点
  128. const checkboxList = table.querySelectorAll('[type="checkbox"]:not(.check-all)');
  129. // 点击全选
  130. checkboxAll.onclick = function() {
  131. checkboxList.forEach(item => {
  132. item.checked = checkboxAll.checked;
  133. })
  134. }
  135. // 判断全选
  136. checkboxList.forEach(item => {
  137. item.onclick = () => {
  138. //console.log(Array.from(checkboxList))
  139. // 将节点转换对象, 判断是否选中
  140. let chs = Array.from(checkboxList).filter(item => {
  141. // 如果选中返回 true
  142. return item.checked === true
  143. });
  144. //console.log(chs)
  145. // 选中的长度等于全选的长度, 标记全选状态
  146. checkboxAll.checked = checkboxList.length === chs.length;
  147. }
  148. })
  149. </script>
  150. </body>
  151. </html>

2. JS模块: Cart.js

  1. /**
  2. * 购物车模块 Cart.js
  3. */
  4. export default class {
  5. // 构造器
  6. constructor(items) {
  7. // 1. 商品总数量
  8. this.total = this.getTotal(items);
  9. // 2. 每个商品金额(数组)
  10. this.money = this.getMoney(items);
  11. // 3. 商品总金额
  12. this.totalMoney = this.getTotalMoney();
  13. // 4. 剩余库存
  14. this.stockNum = this.getStockNum(items);
  15. // 5. 获取优惠折扣
  16. this.reduce = this.getReduce();
  17. // 6. 获取付款价格
  18. this.payMoney = this.getPayMoney();
  19. }
  20. // (一) 计算商品总数量
  21. getTotal(items) {
  22. // 1. 数量数组: 每个商品的数量num字段组成的数组
  23. let numArr = items.map(function(item) {
  24. return item.num;
  25. });
  26. // 2. 计算总数量
  27. return numArr.reduce(function(acc, cur) {
  28. return acc + cur;
  29. });
  30. }
  31. // (二) 计算每个商品的金额
  32. getMoney(items) {
  33. // 金额 = 数量 * 单价
  34. return items.map(function(item) {
  35. return item.num * item.price;
  36. });
  37. }
  38. // (三) 计算商品总金额
  39. getTotalMoney() {
  40. return this.money.reduce(function(acc, cur) {
  41. return acc + cur;
  42. });
  43. }
  44. // (四) 计算库存
  45. getStockNum(items) {
  46. // 库存数组
  47. let stockArr = items.map(function(item) {
  48. return item.stock;
  49. });
  50. return items.map(function(item) {
  51. return item.stock - item.num;
  52. });
  53. }
  54. /**
  55. * 还不会用去用遍历方式来计算判断, 暂时用静态参数判断吧
  56. */
  57. getReduce(totalMoney) {
  58. totalMoney = totalMoney || this.totalMoney;
  59. let reduce = 0;
  60. switch(true) {
  61. case totalMoney >= 5000 :
  62. reduce = 500;
  63. break;
  64. case totalMoney >= 2000 :
  65. reduce = 300;
  66. break;
  67. case totalMoney >= 1000 :
  68. reduce = 100;
  69. break;
  70. case totalMoney >= 800 :
  71. reduce = 60;
  72. break;
  73. case totalMoney >= 500 :
  74. reduce = 50;
  75. break;
  76. }
  77. return reduce;
  78. }
  79. getPayMoney() {
  80. return this.totalMoney - this.reduce;
  81. }
  82. }

3. 运行效果


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