Blogger Information
Blog 29
fans 0
comment 0
visits 19783
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
js完成购物车、es6模块导入问题
手机用户1576673622
Original
807 people have browsed it

1、实现购物车

购物车功能

  1. 全选框选中时,底下的单个商品复选框按钮要全部选中
  2. 单个商品复选框中只要有一个没有被选中,则全选复选框取消选中
  3. 改变商品数量的时候,后边的金额会自动进行加减
  4. 总价和总数量中只计算当前勾选的商品,但是没有勾选的商品中数量和金额可以变动

    实现功能1和2

    js的实现

    1. // 1. 获取全选复选框,所有独立商品的复选框
    2. const checkAll = document.querySelector("#check-all");
    3. const checkItems = document.getElementsByName("item");
    4. // 2. 为全选复选框添加事件: change,当值改变会触发
    5. // console.log(ev.target.checked); // 看当前全选的状态
    6. // 当全选按钮改变,单个值也将跟着改变。 将单个值与全选值保持一致。
    7. checkAll.onchange = ev => checkItems.forEach(item => (item.checked = ev.target.checked));
    8. // 3. 为每个单独的商品复选框添加change
    9. checkItems.forEach(
    10. // 使用every()对单个复选框状态进行判断,如果有一个不为checked状态,则全选复选框显示为不选中
    11. item => (item.onchange = () => (checkAll.checked = [...checkItems].every(item => item.checked)))
    12. );

    jq的实现

    1. $("#check-all").on("change", (ev) => {
    2. // 对全选复选框添加change事件
    3. // 当全选复选框的值改变时,对所有的单品复选框进行同步更新它的选中情况
    4. $('input[name="item"]').each(function () {
    5. // change事件发生时,对每个单品的选中情况进行同步
    6. this.checked = ev.target.checked;
    7. });
    8. });
    9. $('input[name="item"]').each(function () {
    10. // 对每个单品的复选框添加change事件
    11. // 对这个单品复选框集合的checked情况进行every()筛选,
    12. // 当所有的单品复选框都选中时,匹配全选复选框
    13. this.onchange = function () {
    14. // console.log($("#check-all")[0].checked);
    15. // console.log([...$('input[name="item"]')]);
    16. $("#check-all")[0].checked = [...$('input[name="item"]')].every(
    17. (item) => item.checked
    18. );
    19. };
    20. });

    实现功能3和4

    1. // 获取所有的数量控件
    2. const numInput = document.querySelectorAll('tbody input[type="number"');
    3. // 用户更新数量时触发自动计算
    4. numInput.forEach(input => (onchange = autoCalculate));
    5. // 购物车刚加载完成时也应该触发自动计算
    6. window.onload = autoCalculate;
    7. function autoCalculate() {
    8. // 获取单件组成的数组
    9. const prices = document.querySelectorAll("tbody .price");
    10. // prices.forEach(i=>console.log(i.textContent)); 看一下拿到没有
    11. const priceArr = [...prices].map(item => item.textContent * 1);
    12. console.log(priceArr);
    13. // 获取数量组成的数组
    14. const number = document.querySelectorAll("tbody input[type=number]")
    15. const numArr = [...number].map(item => item.value * 1)
    16. console.log(numArr);
    17. // 选中状态金额
    18. // 使用filter()方法,以当前价格的复选框状态作为判断条件,获取到所有的checked为true的单价
    19. const checkedPrice = priceArr.filter(
    20. (item, index) => [...checkItems][index].checked
    21. );
    22. // console.log(checkedPrice);
    23. // 选中状态的数量
    24. const checkedNum = numArr.filter(
    25. (item, index) => [...checkItems][index].checked
    26. );
    27. // console.log(checkedNum);
    28. // 选中状态的总数。 商品总数的获取,可以使用reduce()方法进行累加操作
    29. // console.log(numArr.reduce((pre, cur) => pre + cur));
    30. // 当reduce()中的参数值为空时,reduce()方法会报错,所以需要进行判断
    31. let sum = 0;
    32. if (checkedNum.length !== 0) {
    33. sum = checkedNum.reduce((pre, cur) => pre + cur);
    34. }
    35. // 所有商品总金额。 计算商品的金额:单价 * 数量,还是使用reduce()方法进行计算
    36. // 商品的金额是不随复选框的变动而变动的,它只和数量的变动相关
    37. const amountArr = [priceArr, numArr].reduce((total, curr) =>
    38. total.map((item, index) => item * curr[index])
    39. );
    40. // 过滤。 计算已选中商品的金额数组
    41. const checkedAmount = amountArr.filter(
    42. (item, index) => [...checkItems][index].checked
    43. );
    44. // console.log(checkedAmount);
    45. // console.log(amount);
    46. // 计算已选中商品的总金额
    47. let totalAmount = 0;
    48. if (checkedAmount.length !== 0) {
    49. totalAmount = checkedAmount.reduce((pre, cur) => pre + cur);
    50. }
    51. console.log(totalAmount);
    52. // 将计算结果渲染到购物车中
    53. // 总数量
    54. document.querySelector("#sum").textContent = sum;
    55. // 总金额
    56. document.querySelector("#total-amount").textContent = totalAmount;
    57. // 每个商品的金额
    58. // 根据当前商品的索引和amountArr商品价格数组的索引对应,然后填充到内容中
    59. document
    60. .querySelectorAll(".amount")
    61. .forEach((item, index) => (item.textContent = amountArr[index]));
    62. }

2.es6 模块导入问题

首先要知道什么是模块?模块就是一个 js 代码块。一个封装成模块的 js 文件(比如 module.js),内部成员对外不见,除非导出来。模块要写到一个独立 的 js 文件中,并使用一些特别的语法和关键字

其次是模块解决了什么问题?

  1. 可维护性: 每个模块是独立的,各写各个互不影响,出错直接定位责任人
  2. 可复用性: 只需要一条 import 指令就可以导入
  3. 避免污染全局空间: 模块处在自己的命名空间内
  4. 模块解决了 js 的模块化开发与代码封装问题

模块导入

ES6 之前的模块导入方式是利用 script 标签的 src 属性

  1. <script src="module1.js"></script>

ES6 :

  1. <!-- 导入模块时,必须让type类型为module -->
  2. <script type="module">
  3. // 导入语句,import
  4. // 前面的./不能省略
  5. import { userName, hello, User } from "./module1.js";
  6. </script>

模块内部:

  1. // 关键词export
  2. // export let userName = "天蓬老师";
  3. let userName = "天蓬老师";
  4. function hello(name) {
  5. return "Hello " + name;
  6. }
  7. class User {
  8. constructor(name, price) {
  9. this.name = name;
  10. this.price = price;
  11. }
  12. print() {
  13. return this.name + " => " + this.price + " 元";
  14. }
  15. }
  16. // 私有成员
  17. let salary = 12345;
  18. // 统一导出,推荐使用
  19. export { userName, hello, User };

别名导入

解决重名问题。当前作用域中定义和模块中同名的变量是有问题的,
使用as起一个别名:

  1. export { userName as myName, hello as echo };

导入:

  1. <script type="module">
  2. //import语句不允许写在后边
  3. // 使用别名导入
  4. // import { myName, echo } from "./module2.js";
  5. // let userName;
  6. // console.log(myName, echo(myName));
  7. // 如果还有同名,导入时再次使用别名导入,再改一个名字
  8. import { myName as firstName, echo } from "./module2.js";
  9. let myName;
  10. console.log(firstName);
  11. </script>

默认成员的导入导出

默认模块(成员)写法:

  1. // 默认模块
  2. // 一个模块只能有一个默认成员
  3. // export default let userName = "天蓬老师";
  4. // 上面报错的原因:
  5. // default可以视为一个变量,default = userName;相当于赋值
  6. let userName = "天蓬老师";
  7. export default userName;
  8. function hello(name) {
  9. return "Hello " + name;
  10. }
  11. export default hello
  12. // 默认导出的成员不要加大括号
  13. // export default { hello }; 报错
  14. // 导出列表中,既有默认成员,也有普通成员 怎么办?
  15. // email是非静态成员(普通成员)
  16. let email = "admin@php.cn";
  17. // 认为hello是默认成员 用as加上属性 此时email是普通成员 hello是默认成员
  18. export { email, hello as default };

接受既有默认与有非默认成员的方法:默认成员不要带大括号,普通成员带上。

  1. // 接收既有默认与有非默认
  2. import hello, { email } from "./module3.js";

命名空间的使用方法

  1. <script type="module">
  2. // 命名空间: 是一个容器,内部可以包括任何类型的数据
  3. // 命名空间是一个对象,可以挂载到当前的全局中
  4. //函数挂载到 namespace 这个命名空间上。
  5. import * as namespace from "./module1.js";
  6. let userName;
  7. let hello = () => {};
  8. class User {}
  9. //命名空间其实就是一个对象,可以用对象的方式访问。
  10. console.log(namespace);
  11. console.log(namespace.userName);
  12. console.log(namespace.hello(namespace.userName));
  13. console.log(new namespace.User("电脑", 4999).print());
  14. </script>
Correction status:Uncorrected

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