博客列表 >【JavaScript案例】购物车全选和自动计算金额案例(附源码)及ES6模块化编程导入导出详解

【JavaScript案例】购物车全选和自动计算金额案例(附源码)及ES6模块化编程导入导出详解

 一纸荒凉* Armani
 一纸荒凉* Armani原创
2021年04月13日 16:30:094030浏览

购物车商品全选和金额计算案例

  1. table {
  2. border-collapse: collapse;
  3. width: 90%;
  4. text-align: center;
  5. margin: auto;
  6. }
  7. table caption {
  8. margin-bottom: 15px;
  9. font-size: 1.5rem;
  10. }
  11. table th,
  12. table td {
  13. border-bottom: 1px solid #ccc;
  14. padding: 5px;
  15. font-weight: normal;
  16. }
  17. table thead tr:first-of-type {
  18. background-color: #e6e6e6;
  19. height: 3em;
  20. }
  21. table input[type="checkbox"] {
  22. width: 1.5em;
  23. height: 1.5em;
  24. }
  25. table tbody tr {
  26. border-bottom: 1px solid #ccc;
  27. }
  28. table tbody tr:hover {
  29. background-color: #f6f6f6;
  30. cursor: pointer;
  31. }
  32. tbody img {
  33. width: 3em;
  34. }
  35. tbody input[type="number"] {
  36. width: 3em;
  37. }
  38. button {
  39. width: 150px;
  40. height: 30px;
  41. outline: none;
  42. border: none;
  43. background-color: teal;
  44. color: white;
  45. letter-spacing: 5px;
  46. }
  47. button:hover {
  48. opacity: 0.7;
  49. cursor: pointer;
  50. }
  1. <table>
  2. <caption>
  3. 购物车
  4. </caption>
  5. <thead>
  6. <tr>
  7. <!-- 全选复选框 -->
  8. <th><input type="checkbox" name="checkAll" id="check-all" checked /><label for="check-all">全选</label></th>
  9. <th>图片</th>
  10. <th>品名</th>
  11. <th>单位</th>
  12. <th>单价/元</th>
  13. <th>数量</th>
  14. <th>金额/元</th>
  15. </tr>
  16. </thead>
  17. <tbody>
  18. <tr>
  19. <td>
  20. <input type="checkbox" name="item" value="SN-1020" checked />
  21. </td>
  22. <td>
  23. <a href=""><img src="images/p1.jpg" alt="" /></a>
  24. </td>
  25. <td>iPhone 11</td>
  26. <td></td>
  27. <td class="price">4799</td>
  28. <td><input type="number" min="1" value="1" /></td>
  29. <td class="amount">4799</td>
  30. </tr>
  31. <tr>
  32. <td>
  33. <input type="checkbox" name="item" value="SN-1020" checked />
  34. </td>
  35. <td>
  36. <a href=""><img src="images/p2.jpg" alt="" /></a>
  37. </td>
  38. <td>小米pro 11</td>
  39. <td></td>
  40. <td class="price">3999</td>
  41. <td><input type="number" min="1" value="2" /></td>
  42. <td class="amount">7998</td>
  43. </tr>
  44. <tr>
  45. <td>
  46. <input type="checkbox" name="item" value="SN-1030" checked />
  47. </td>
  48. <td>
  49. <a href=""><img src="images/p3.jpg" alt="" /></a>
  50. </td>
  51. <td>MacBook Pro</td>
  52. <td></td>
  53. <td class="price">18999</td>
  54. <td><input type="number" min="1" value="1" /></td>
  55. <td class="amount">18999</td>
  56. </tr>
  57. <tr>
  58. <td>
  59. <input type="checkbox" name="item" value="SN-1040" checked />
  60. </td>
  61. <td>
  62. <a href=""><img src="images/p4.jpg" alt="" /></a>
  63. </td>
  64. <td>小米75电视</td>
  65. <td></td>
  66. <td class="price">5999</td>
  67. <td><input type="number" min="1" value="2" /></td>
  68. <td class="amount">11998</td>
  69. </tr>
  70. <tr>
  71. <td>
  72. <input type="checkbox" name="item" value="SN-1050" checked />
  73. </td>
  74. <td>
  75. <a href=""><img src="images/p5.jpg" alt="" /></a>
  76. </td>
  77. <td>Canon 90D单反</td>
  78. <td></td>
  79. <td class="price">9699</td>
  80. <td><input type="number" min="1" value="1" /></td>
  81. <td class="amount">9699</td>
  82. </tr>
  83. </tbody>
  84. <tfoot>
  85. <tr style="font-weight: bolder; font-size: 1.2em">
  86. <td colspan="5">总计:</td>
  87. <td id="sum">7</td>
  88. <td id="total-amount">53493</td>
  89. </tr>
  90. </tfoot>
  91. </table>
  92. <div style="width: 90%; margin: 10px auto">
  93. <button style="float: right; width: 100px">结算</button>
  94. </div>
  1. // 1.获取全选按钮,每个独立的商品复选框
  2. const checkAll = document.querySelector('#check-all');
  3. const checkItems = document.getElementsByName("item");
  4. // 2. 将当前的全选的状态变化赋值给每个商品复选框
  5. checkAll.addEventListener('change', (ev) => {
  6. checkItems.forEach(item => {
  7. item.checked = ev.target.checked
  8. });
  9. // 根据选中状态计算商品的总金额和总数量
  10. amountTotal();
  11. });
  12. // 3. 为每个单独商品的复选框添加事件
  13. checkItems.forEach(item => {
  14. item.addEventListener('change', () => {
  15. checkAll.checked = [...checkItems].every(item => item.checked);
  16. // 根据选中状态计算商品的总金额和总数量
  17. amountTotal();
  18. })
  19. });
  20. // 4.为数量按钮添加事件,动态计算商品总量和金额
  21. const numInput = document.querySelectorAll('tbody input[type="number"]');
  22. numInput.forEach(input => input.addEventListener('change', autoCalculate));
  23. // 页面加载完成自动计算
  24. window.addEventListener('load', autoCalculate);
  25. // 5. 自动计算方法
  26. function autoCalculate() {
  27. // 获取所有商品单价节点
  28. const prices = document.querySelectorAll('tbody .price');
  29. // 获得所有商品单价金额
  30. const priceArr = [...prices].map(price => +price.innerText);
  31. console.log(priceArr);
  32. // 获取所有数量按钮节点
  33. const numbers = document.querySelectorAll('tbody input[type="number"]');
  34. // 获得所有商品数量数组
  35. const numArr = [...numbers].map(num => +num.value);
  36. console.log(numArr);
  37. // 计算单个商品金额 = 数量*单价
  38. let amountArr = [priceArr, numArr].reduce((total, curr) => {
  39. return total.map((item, index) => {
  40. return item * curr[index]
  41. })
  42. });
  43. // 将每一个商品金额渲染到页面中
  44. document.querySelectorAll('.amount').forEach((item, index) => {
  45. item.innerText = amountArr[index]
  46. })
  47. // 计算总数量总数量
  48. amountTotal();
  49. }
  50. // 根据复选框选中状态计算总金额和总数量
  51. function amountTotal() {
  52. // 获取所有数量按钮节点
  53. const numbers = document.querySelectorAll('tbody input[type="number"]');
  54. // 获得所有商品数量数组
  55. const numArr = [...numbers].map(num => {
  56. // 获取当前数量节点父节点下的check复选框
  57. const check = num.parentElement.parentElement.querySelector('input[type="checkbox"]');
  58. // 过滤出选中的商品数量数组
  59. return check.checked ? +num.value : 0;
  60. });
  61. console.log(numArr);
  62. // 获取所有单个商品总金额节点
  63. const amounts = document.querySelectorAll('.amount');
  64. // 获得所有单个商品总金额数组
  65. const amountArr = [...amounts].map(amount => {
  66. // 获取当前数量节点父节点下的check复选框
  67. const check = amount.parentElement.querySelector('input[type="checkbox"]');
  68. // 过滤出选中的商品数量数组
  69. return check.checked ? +amount.innerText : 0;
  70. });
  71. console.log(amountArr);
  72. // 计算总数量
  73. document.querySelector('#sum').innerText = `${numArr.reduce((pre, cur) => pre + cur)}件`;
  74. // 计算总金额
  75. document.querySelector('#total-amount').textContent = `¥${amountArr.reduce((pre, curr) => pre + curr)}`;
  76. }

实现效果:

预览地址:http://easys.ltd/shopcart/


ES6的模块化实现

一个模块就是一个独立的js代码块文件,下面将介绍module中的export和import概念。
ES6 module 模块功能使用 export 导出模块的内容,并使用 import 导入模块的内容。

示例:

  1. // math.js(定义模块)
  2. exports.add = function(a, b) {
  3. return a + b;
  4. };
  5. // app.js(使用模块)
  6. var math = require('./math');
  7. var rs = math.add(1, 2);
  8. console.log(rs);

(导出)export用于规定模块的对外接口

创建ES6模块时,可使用export关键字导出(对外提供)模块的内容,如函数、对象以及原始变量等等。

export 导出方案有2种:Named exports(命名导出;每个模块可有多个)和 Default exports(默认导出;每个模块只能一个)。

Named exports 命名导出

说明:使用 export + 名称 的形式导出模块的内容。

注意:在 import 导入过程中,需指定这些名称。

  1. // 1) 声明时导出
  2. export let myVar = 'a';
  3. export const MY_CONST = 'c';
  4. export const getName = () => {}...
  5. export const getAge = () => {}...
  6. export function getName(){
  7. return ...
  8. }
  9. // 2) 声明后导出
  10. var myVar = 'a';
  11. export const MY_CONST = 'c';
  12. const getName = () =>{} ...
  13. const getAge = () =>{} ...
  14. export {myVar,MY_CONST,getName,getAge}
  15. // 3) 别名导出
  16. var myVar3 = 'a';
  17. export { myVar3 as myVar };
  18. // math.js
  19. export function add(a, b) {
  20. return a + b;
  21. }
  22. // app.js:导入含有命名导出的模块时,需要指定成员名称
  23. import { add } from './math.js';
  24. console.log(add(1, 2)); // => 3

Default exports 默认导出

说明:使用 export default 导出模块默认的内容,每个模块只能有一个 export default。

  1. // 1) 声明时导出 匿名函数
  2. export default expression;
  3. export default function() {
  4. return ...
  5. }
  6. export default () => {}...
  7. // 2) 别名设置为default导出
  8. export default function name1() {}
  9. export { name1 as default };

默认导出声明的是一个表达式,通常没有名字,导入时需指定模块名称。

  1. // math.js
  2. export function add(a, b) {
  3. return a + b;
  4. }
  5. export default function cube(x) {
  6. return x * x * x;
  7. }
  8. // app.js:导入默认导出的模块时,需要指定模块名称
  9. import cube from './math.js';
  10. console.log(cube(3)); // => 27
  11. // 若想同时导入含有默认导出、命名导出的模块,只需要导入时用','隔开
  12. import cube, { add } from './math.js';

(导入)import用于输入其他模块提供的功能

  1. // 1)导入模块的默认导出内容
  2. import defaultExport from 'module-name';
  3. // 2)导入模块的命名导出内容
  4. import { export1, export2 } from 'module-name';
  5. import { export as alias } from 'module-name'; // 修改别名
  6. import * as name from 'module-name'; // 导入模块内的所有命名导出内容
  7. // 3)导入模块的默认导出、命名导出
  8. import defaultExport, { export1, export2 } from 'module-name';
  9. import defaultExport, * as name from 'module-name';

1) 导入默认导出

说明:导入默认导出的模块时,需要指定模块名称

  1. // math.js
  2. export default function cube(x) {
  3. return x * x * x;
  4. }
  5. // app.js:导入默认导出的模块时,需要指定模块名称
  6. import cube from './math.js';
  7. console.log(cube(3)); // => 27
  8. import user from './default.js' // 如果使用这种引入请导出匿名函数

2) 导入命名导出

说明:导入模块时可使用大括号包含指定命名成员;也可以用 * as moduleName 的形式把此模块的所有命名导出作为某个对象的成员。

  1. // math.js
  2. export function add(a, b) {
  3. return a + b;
  4. }
  5. // app.js:指定使用math模块的add命名导出
  6. import { add } from './math.js';
  7. console.log(add(1, 2)); // => 3
  8. // 按需引入
  9. import { getName, getAge } from './utils.js'
  10. // 导入所有的命名导出作为math对象的成员
  11. import * as math from './math.js';
  12. console.log(math.add(1, 2)); // => 3
  13. // 将引入的模块赋值到user对象中
  14. import * as user from './utils.js'
  15. // 结构会变成如下样式
  16. // user = {
  17. // getAge: function(){ ... }
  18. // getName: function(){ ... }
  19. // }

3) 仅导入模块

说明:仅导入模块时,只会执行模块的全局函数,不会导入任何成员。

  1. // math.js
  2. export function add(a, b) {
  3. return a + b;
  4. }
  5. function hello() {
  6. console.log('hello math.js');
  7. }
  8. hello();
  9. // app.js
  10. import { add } from './math.js'; // => hello math.js

注意:模块成员在当前使用环境中,既不能重复声明,也不能更新(相对应常量)

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