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>

更多相关文章

  1. 面向对象的相关操作
  2. LsLoader——通用移动端Web App离线化方案
  3. Python使用socket搭建TCP服务器(后期的客户端:GPRS模块)
  4. WEB请求处理(2):Nginx 请求反向代理
  5. PHP:OOP基础/类(对象抽象化的结果)与对象 (类实例化结果)/构造方
  6. 【PHP 面向对象】面向对象(OOP)编程知识点归纳总结(一)
  7. Ryu:模块间通信机制分析
  8. Ansible 架构与工作原理
  9. 学 Win32 汇编[33] - 探讨 Win32 汇编的模块化编程

随机推荐

  1. Android关于java.lang.NoClassDefFoundEr
  2. Android 资源文件中的符号含义与说明: @ ?
  3. 平时积累(四)
  4. Android快速开发框架
  5. android之ListView布局
  6. 安卓手机常见名词解释
  7. MonkeyRunner与模拟器连接
  8. Android应用程序四大组件
  9. Android的布局控件----LinearLayout(线性
  10. Android 在 xml中定义图片