Blogger Information
Blog 25
fans 0
comment 0
visits 13653
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
JS实现购物车功能功能:全选、全不选,单选等。
安超
Original
715 people have browsed it

1.JS实现购物车的技术分析

1.1本案例为用JS模块实现购物车的功能:全选、全不选,单选等。

模块用默认导出类实现,export default class{}.class中的数据主要包括:所有商品的和、每个商品的总价、所有商品的总价之和等,有属性和方法。
效果见图:
购物车效果图
购物车效果图
购物车效果图

  1. export default class {
  2. constructor(items){
  3. // 所有商品的数量总和
  4. this.total = this.getNum(items);
  5. // 购买的单个商品的总价,是个数组
  6. this.price = this.getPrice(items);
  7. // 所有商品的价格之和
  8. this.totalMoney = this.getTotalMoney(items);
  9. }
  10. // 获取所有商品数量的总和
  11. getNum(items){
  12. // 取得商品的数量数组
  13. let numArr = items.map(item=>item.num);
  14. // 取得商品的所有总数
  15. let sum = numArr.reduce((acc,item)=>acc +=item);
  16. return sum; //和
  17. }
  18. // 获取购买的所有单个商品的总价 ,是数组
  19. getPrice(items){
  20. return items.map(item=>item.num*item.price); //数组
  21. }
  22. // 计算所有商品价格的总和
  23. getTotalMoney(items){
  24. return this.price.reduce((acc,item)=> acc += item); //数
  25. }
  26. }

1.2购物车的脚本文档JS中,主要功能有:

1.2.1 利用现有数据动态创建table
  1. <script type="module">
  2. //商品信息,可以从服务器端获取,此处简单的罗列出来
  3. const items =[
  4. {id:286,name:"酸奶",units:"箱",price:50,num:3},
  5. {id:870,name:"苹果",units:"千克",price:10,num:1},
  6. {id:633,name:"外套",units:"件",price:300,num:1},
  7. {id:153,name:"皮鞋",units:"双",price:400,num:1},
  8. {id:109,name:"手机",units:"台",price:5000,num:1},
  9. ];
  10. // 1. 导入默认模块时,命名权在前端
  11. import Cart from './cart.js';
  12. // 2.实例化类 new
  13. const itemNew = new Cart(items);
  14. // 3.获取购物车表格
  15. const table = document.querySelector('table');
  16. // 4. 将商品渲染到购物车元素中 tbody,新方法createTBody()
  17. // 4.1 创建tbody,商品容器
  18. const tbody = table.createTBody();
  19. // 4.2 创建tbody的内容 用forEach()函数
  20. items.forEach((item,key)=>{
  21. let tr = `
  22. <tr>
  23. <td><input type ="checkbox" checked> </td>
  24. <td>${item.id}</td>
  25. <td>${item.name}</td>
  26. <td>${item.units}</td>
  27. <td>${item.price}</td>
  28. <td><input type="number" value="${item.num}" min="0"></td>
  29. <td class = "money">${itemNew.price[key]}</td>
  30. </tr>
  31. `;
  32. tbody.insertAdjacentHTML('beforeend',tr);
  33. });
  34. // 将相关统计数据放到表格的尾部里
  35. const tfoot = table.createTFoot();
  36. const tr = `
  37. <tr>
  38. <td colspan="5">总计</td>
  39. <td class = "total">${itemNew.total}</td>
  40. <td class = "total-money">${itemNew.totalMoney}</td>
  41. </tr>
  42. `;
  43. tfoot.insertAdjacentHTML('beforeend',tr);
1.2.2 input框的事件响应函数

主要有三个事件:类型为number的input的改变事件(oninput)、总选择框和单选择框的click事件。

  1. document.querySelectorAll('input[type="number"]').forEach((item,key)=>{
  2. item.oninput = function(){
  3. // item.value是个字符串,需要转换为数值,字符串乘以1可以转换为数值
  4. // console.log(item.value*1 +10); 将字符串转换为数值
  5. // // 下列的方法只能获取默认数组里的值
  6. // // 1. 改变单项的数量后改变数量的总和
  7. // //1.1 获取单项的改变值
  8. let num = items[key].num = item.value*1;
  9. // // 1.2 计算所有商品的总和
  10. // itemNew.total = itemNew.getNum(items);
  11. //计算每个商品的总金额
  12. itemNew.price[key] = num*items[key].price;
  13. // //获取单项改变后的所有项值的和 itemNew.total
  14. // itemNew.totalMoney = itemNew.getTotalMoney(items);
  15. // // 将改变后的金额填入单项总金额里
  16. document.querySelectorAll('.money')[key].textContent = itemNew.price[key];
  17. // // 将改变后的所有商品的金额填入总金额项目里
  18. // document.querySelector('.total-money').textContent = itemNew.totalMoney;
  19. // document.querySelector('.total').textContent = itemNew.total;
  20. // // 上述的方法只能获取默认数组里的值
  21. // 当类型为number的input框改变时,计算所有的商品的数量和
  22. let checkedInput = tbody.querySelectorAll('input[type=checkbox]:checked');
  23. // console.log(checkedInput);
  24. let checkedNumber = [...checkedInput].map(ele => ele.parentNode.parentNode);
  25. itemNew.total =[...checkedNumber].map(ele => ele.querySelector('input[type=number]').value*1).reduce((acc,cur) => acc += cur);
  26. document.querySelector('.total').textContent = itemNew.total;
  27. // 计算选取的所有商品的价格总和
  28. let checkArr_2 = [...checkedInput].map(ele=>ele.parentNode.parentNode);
  29. let checkArr_32 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent));
  30. document.querySelector('.total-money').textContent = checkArr_32.reduce((acc,cur) => acc+=cur);
  31. }
  32. });
  33. // 1. 实现全选、全不选
  34. // 1.1 选取总的选择框
  35. let checkAll = document.querySelector('.check-all');
  36. // 1.2 选取tbody里的所有checkbox
  37. let tbodyCheck = document.querySelectorAll('tbody input[type=checkbox]');
  38. // 1.3 点击总的选择框后,根据总选择框的状态决定各个分选择框的状态
  39. checkAll.onclick = function(){
  40. if(checkAll.checked === true){
  41. [...tbodyCheck].forEach(item=>item.checked = true)
  42. let tbodyCheck_1 = document.querySelectorAll('tbody input[type=number]');
  43. // console.log(tbodyCheck_1);
  44. // 计算所有的项目之和
  45. let total = [...tbodyCheck_1].map(ele => ele.value*1).reduce((acc,cur) =>acc += cur);
  46. document.querySelector('.total').textContent = total;
  47. // 计算所有的价格之和
  48. let tbodyCheck_2 = document.querySelectorAll('tbody tr');
  49. document.querySelector('.total-money').textContent = [...tbodyCheck_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent)).reduce((acc,cur) => acc += cur );
  50. } else{
  51. [...tbodyCheck].forEach(item=>item.checked = false);
  52. document.querySelector('.total').textContent = 0;
  53. document.querySelector('.total-money').textContent = 0;
  54. // 能否重置数量的数值?
  55. // [...tbodyCheck].forEach(item=>{
  56. // item.value = 0;
  57. // });
  58. }
  59. };
  60. // 只要有一个没选,总选框就取消
  61. [...tbodyCheck].forEach(ele=>ele.onclick = function(ev){
  62. // 选择处于选择状态的input框
  63. let checkAll_2 = document.querySelectorAll('tbody input[type=checkbox]:checked');
  64. // 选择选中的input框后边的类型为number的input框
  65. let checkArr_2 = [...checkAll_2].map(ele=>ele.parentNode.parentNode);
  66. // let temp = [...checkAll_2].map(ele => [...(ele.parentNode.parentNode.children)]);
  67. // let temp_1 = [...temp].map(ele=>ele[5].children)
  68. // 获取处于选择状态的选择框的type为number的input框,有些麻烦,*1后有字符串变为数值
  69. let checkArr_31 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1);
  70. let checkArr_32 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent));
  71. console.log(checkArr_32);
  72. // 必须要有初始值0,否则当所有的框都不选时,总的数值里没有值
  73. itemNew.total = checkArr_31.reduce((acc,cur)=>acc + cur,0);
  74. document.querySelector('.total').textContent = itemNew.total;
  75. // 计算所有的选中的样品的价格之和
  76. document.querySelector('.total-money').textContent = checkArr_32.reduce((acc,cur) => acc+=cur);
  77. let findArr = [...tbodyCheck].map(ele=>ele.checked === true);
  78. // console.log(findArr);
  79. let findArrFalse = findArr.find(ele=>ele === false);
  80. // 如果findArrFlase里有false,则全选框checked = false
  81. if(findArrFalse === false){
  82. checkAll.checked = false;
  83. }else{
  84. checkAll.checked = true;
  85. }
  86. });
Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:完成的很好, 继续加油
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!