Correction status:Uncorrected
Teacher's comments:
购物车功能
总价和总数量中只计算当前勾选的商品,但是没有勾选的商品中数量和金额可以变动
js的实现
// 1. 获取全选复选框,所有独立商品的复选框
const checkAll = document.querySelector("#check-all");
const checkItems = document.getElementsByName("item");
// 2. 为全选复选框添加事件: change,当值改变会触发
// console.log(ev.target.checked); // 看当前全选的状态
// 当全选按钮改变,单个值也将跟着改变。 将单个值与全选值保持一致。
checkAll.onchange = ev => checkItems.forEach(item => (item.checked = ev.target.checked));
// 3. 为每个单独的商品复选框添加change
checkItems.forEach(
// 使用every()对单个复选框状态进行判断,如果有一个不为checked状态,则全选复选框显示为不选中
item => (item.onchange = () => (checkAll.checked = [...checkItems].every(item => item.checked)))
);
jq的实现
$("#check-all").on("change", (ev) => {
// 对全选复选框添加change事件
// 当全选复选框的值改变时,对所有的单品复选框进行同步更新它的选中情况
$('input[name="item"]').each(function () {
// change事件发生时,对每个单品的选中情况进行同步
this.checked = ev.target.checked;
});
});
$('input[name="item"]').each(function () {
// 对每个单品的复选框添加change事件
// 对这个单品复选框集合的checked情况进行every()筛选,
// 当所有的单品复选框都选中时,匹配全选复选框
this.onchange = function () {
// console.log($("#check-all")[0].checked);
// console.log([...$('input[name="item"]')]);
$("#check-all")[0].checked = [...$('input[name="item"]')].every(
(item) => item.checked
);
};
});
// 获取所有的数量控件
const numInput = document.querySelectorAll('tbody input[type="number"');
// 用户更新数量时触发自动计算
numInput.forEach(input => (onchange = autoCalculate));
// 购物车刚加载完成时也应该触发自动计算
window.onload = autoCalculate;
function autoCalculate() {
// 获取单件组成的数组
const prices = document.querySelectorAll("tbody .price");
// prices.forEach(i=>console.log(i.textContent)); 看一下拿到没有
const priceArr = [...prices].map(item => item.textContent * 1);
console.log(priceArr);
// 获取数量组成的数组
const number = document.querySelectorAll("tbody input[type=number]")
const numArr = [...number].map(item => item.value * 1)
console.log(numArr);
// 选中状态金额
// 使用filter()方法,以当前价格的复选框状态作为判断条件,获取到所有的checked为true的单价
const checkedPrice = priceArr.filter(
(item, index) => [...checkItems][index].checked
);
// console.log(checkedPrice);
// 选中状态的数量
const checkedNum = numArr.filter(
(item, index) => [...checkItems][index].checked
);
// console.log(checkedNum);
// 选中状态的总数。 商品总数的获取,可以使用reduce()方法进行累加操作
// console.log(numArr.reduce((pre, cur) => pre + cur));
// 当reduce()中的参数值为空时,reduce()方法会报错,所以需要进行判断
let sum = 0;
if (checkedNum.length !== 0) {
sum = checkedNum.reduce((pre, cur) => pre + cur);
}
// 所有商品总金额。 计算商品的金额:单价 * 数量,还是使用reduce()方法进行计算
// 商品的金额是不随复选框的变动而变动的,它只和数量的变动相关
const amountArr = [priceArr, numArr].reduce((total, curr) =>
total.map((item, index) => item * curr[index])
);
// 过滤。 计算已选中商品的金额数组
const checkedAmount = amountArr.filter(
(item, index) => [...checkItems][index].checked
);
// console.log(checkedAmount);
// console.log(amount);
// 计算已选中商品的总金额
let totalAmount = 0;
if (checkedAmount.length !== 0) {
totalAmount = checkedAmount.reduce((pre, cur) => pre + cur);
}
console.log(totalAmount);
// 将计算结果渲染到购物车中
// 总数量
document.querySelector("#sum").textContent = sum;
// 总金额
document.querySelector("#total-amount").textContent = totalAmount;
// 每个商品的金额
// 根据当前商品的索引和amountArr商品价格数组的索引对应,然后填充到内容中
document
.querySelectorAll(".amount")
.forEach((item, index) => (item.textContent = amountArr[index]));
}
首先要知道什么是模块?模块就是一个 js 代码块。一个封装成模块的 js 文件(比如 module.js),内部成员对外不见,除非导出来。模块要写到一个独立 的 js 文件中,并使用一些特别的语法和关键字
其次是模块解决了什么问题?
ES6 之前的模块导入方式是利用 script 标签的 src 属性
<script src="module1.js"></script>
ES6 :
<!-- 导入模块时,必须让type类型为module -->
<script type="module">
// 导入语句,import
// 前面的./不能省略
import { userName, hello, User } from "./module1.js";
</script>
模块内部:
// 关键词export
// export let userName = "天蓬老师";
let userName = "天蓬老师";
function hello(name) {
return "Hello " + name;
}
class User {
constructor(name, price) {
this.name = name;
this.price = price;
}
print() {
return this.name + " => " + this.price + " 元";
}
}
// 私有成员
let salary = 12345;
// 统一导出,推荐使用
export { userName, hello, User };
解决重名问题。当前作用域中定义和模块中同名的变量是有问题的,
使用as起一个别名:
export { userName as myName, hello as echo };
导入:
<script type="module">
//import语句不允许写在后边
// 使用别名导入
// import { myName, echo } from "./module2.js";
// let userName;
// console.log(myName, echo(myName));
// 如果还有同名,导入时再次使用别名导入,再改一个名字
import { myName as firstName, echo } from "./module2.js";
let myName;
console.log(firstName);
</script>
默认模块(成员)写法:
// 默认模块
// 一个模块只能有一个默认成员
// export default let userName = "天蓬老师";
// 上面报错的原因:
// default可以视为一个变量,default = userName;相当于赋值
let userName = "天蓬老师";
export default userName;
function hello(name) {
return "Hello " + name;
}
export default hello
// 默认导出的成员不要加大括号
// export default { hello }; 报错
// 导出列表中,既有默认成员,也有普通成员 怎么办?
// email是非静态成员(普通成员)
let email = "admin@php.cn";
// 认为hello是默认成员 用as加上属性 此时email是普通成员 hello是默认成员
export { email, hello as default };
接受既有默认与有非默认成员的方法:默认成员不要带大括号,普通成员带上。
// 接收既有默认与有非默认
import hello, { email } from "./module3.js";
<script type="module">
// 命名空间: 是一个容器,内部可以包括任何类型的数据
// 命名空间是一个对象,可以挂载到当前的全局中
//函数挂载到 namespace 这个命名空间上。
import * as namespace from "./module1.js";
let userName;
let hello = () => {};
class User {}
//命名空间其实就是一个对象,可以用对象的方式访问。
console.log(namespace);
console.log(namespace.userName);
console.log(namespace.hello(namespace.userName));
console.log(new namespace.User("电脑", 4999).print());
</script>