Blogger Information
Blog 128
fans 9
comment 5
visits 240919
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
【JavaScript案例】购物车全选和自动计算金额案例(附源码)及ES6模块化编程导入导出详解
 一纸荒凉* Armani
Original
4031 people have browsed it

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

  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

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

Correcting teacher:天蓬老师天蓬老师

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