Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:完成的很好, 继续加油
模块用默认导出类实现,export default class{}.class中的数据主要包括:所有商品的和、每个商品的总价、所有商品的总价之和等,有属性和方法。
效果见图:
export default class {
constructor(items){
// 所有商品的数量总和
this.total = this.getNum(items);
// 购买的单个商品的总价,是个数组
this.price = this.getPrice(items);
// 所有商品的价格之和
this.totalMoney = this.getTotalMoney(items);
}
// 获取所有商品数量的总和
getNum(items){
// 取得商品的数量数组
let numArr = items.map(item=>item.num);
// 取得商品的所有总数
let sum = numArr.reduce((acc,item)=>acc +=item);
return sum; //和
}
// 获取购买的所有单个商品的总价 ,是数组
getPrice(items){
return items.map(item=>item.num*item.price); //数组
}
// 计算所有商品价格的总和
getTotalMoney(items){
return this.price.reduce((acc,item)=> acc += item); //数
}
}
<script type="module">
//商品信息,可以从服务器端获取,此处简单的罗列出来
const items =[
{id:286,name:"酸奶",units:"箱",price:50,num:3},
{id:870,name:"苹果",units:"千克",price:10,num:1},
{id:633,name:"外套",units:"件",price:300,num:1},
{id:153,name:"皮鞋",units:"双",price:400,num:1},
{id:109,name:"手机",units:"台",price:5000,num:1},
];
// 1. 导入默认模块时,命名权在前端
import Cart from './cart.js';
// 2.实例化类 new
const itemNew = new Cart(items);
// 3.获取购物车表格
const table = document.querySelector('table');
// 4. 将商品渲染到购物车元素中 tbody,新方法createTBody()
// 4.1 创建tbody,商品容器
const tbody = table.createTBody();
// 4.2 创建tbody的内容 用forEach()函数
items.forEach((item,key)=>{
let tr = `
<tr>
<td><input type ="checkbox" checked> </td>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.units}</td>
<td>${item.price}</td>
<td><input type="number" value="${item.num}" min="0"></td>
<td class = "money">${itemNew.price[key]}</td>
</tr>
`;
tbody.insertAdjacentHTML('beforeend',tr);
});
// 将相关统计数据放到表格的尾部里
const tfoot = table.createTFoot();
const tr = `
<tr>
<td colspan="5">总计</td>
<td class = "total">${itemNew.total}</td>
<td class = "total-money">${itemNew.totalMoney}</td>
</tr>
`;
tfoot.insertAdjacentHTML('beforeend',tr);
主要有三个事件:类型为number的input的改变事件(oninput)、总选择框和单选择框的click事件。
document.querySelectorAll('input[type="number"]').forEach((item,key)=>{
item.oninput = function(){
// item.value是个字符串,需要转换为数值,字符串乘以1可以转换为数值
// console.log(item.value*1 +10); 将字符串转换为数值
// // 下列的方法只能获取默认数组里的值
// // 1. 改变单项的数量后改变数量的总和
// //1.1 获取单项的改变值
let num = items[key].num = item.value*1;
// // 1.2 计算所有商品的总和
// itemNew.total = itemNew.getNum(items);
//计算每个商品的总金额
itemNew.price[key] = num*items[key].price;
// //获取单项改变后的所有项值的和 itemNew.total
// itemNew.totalMoney = itemNew.getTotalMoney(items);
// // 将改变后的金额填入单项总金额里
document.querySelectorAll('.money')[key].textContent = itemNew.price[key];
// // 将改变后的所有商品的金额填入总金额项目里
// document.querySelector('.total-money').textContent = itemNew.totalMoney;
// document.querySelector('.total').textContent = itemNew.total;
// // 上述的方法只能获取默认数组里的值
// 当类型为number的input框改变时,计算所有的商品的数量和
let checkedInput = tbody.querySelectorAll('input[type=checkbox]:checked');
// console.log(checkedInput);
let checkedNumber = [...checkedInput].map(ele => ele.parentNode.parentNode);
itemNew.total =[...checkedNumber].map(ele => ele.querySelector('input[type=number]').value*1).reduce((acc,cur) => acc += cur);
document.querySelector('.total').textContent = itemNew.total;
// 计算选取的所有商品的价格总和
let checkArr_2 = [...checkedInput].map(ele=>ele.parentNode.parentNode);
let checkArr_32 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent));
document.querySelector('.total-money').textContent = checkArr_32.reduce((acc,cur) => acc+=cur);
}
});
// 1. 实现全选、全不选
// 1.1 选取总的选择框
let checkAll = document.querySelector('.check-all');
// 1.2 选取tbody里的所有checkbox
let tbodyCheck = document.querySelectorAll('tbody input[type=checkbox]');
// 1.3 点击总的选择框后,根据总选择框的状态决定各个分选择框的状态
checkAll.onclick = function(){
if(checkAll.checked === true){
[...tbodyCheck].forEach(item=>item.checked = true)
let tbodyCheck_1 = document.querySelectorAll('tbody input[type=number]');
// console.log(tbodyCheck_1);
// 计算所有的项目之和
let total = [...tbodyCheck_1].map(ele => ele.value*1).reduce((acc,cur) =>acc += cur);
document.querySelector('.total').textContent = total;
// 计算所有的价格之和
let tbodyCheck_2 = document.querySelectorAll('tbody tr');
document.querySelector('.total-money').textContent = [...tbodyCheck_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent)).reduce((acc,cur) => acc += cur );
} else{
[...tbodyCheck].forEach(item=>item.checked = false);
document.querySelector('.total').textContent = 0;
document.querySelector('.total-money').textContent = 0;
// 能否重置数量的数值?
// [...tbodyCheck].forEach(item=>{
// item.value = 0;
// });
}
};
// 只要有一个没选,总选框就取消
[...tbodyCheck].forEach(ele=>ele.onclick = function(ev){
// 选择处于选择状态的input框
let checkAll_2 = document.querySelectorAll('tbody input[type=checkbox]:checked');
// 选择选中的input框后边的类型为number的input框
let checkArr_2 = [...checkAll_2].map(ele=>ele.parentNode.parentNode);
// let temp = [...checkAll_2].map(ele => [...(ele.parentNode.parentNode.children)]);
// let temp_1 = [...temp].map(ele=>ele[5].children)
// 获取处于选择状态的选择框的type为number的input框,有些麻烦,*1后有字符串变为数值
let checkArr_31 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1);
let checkArr_32 = [...checkArr_2].map(ele=>ele.querySelector('input[type=number]').value*1*(ele.children[4].textContent));
console.log(checkArr_32);
// 必须要有初始值0,否则当所有的框都不选时,总的数值里没有值
itemNew.total = checkArr_31.reduce((acc,cur)=>acc + cur,0);
document.querySelector('.total').textContent = itemNew.total;
// 计算所有的选中的样品的价格之和
document.querySelector('.total-money').textContent = checkArr_32.reduce((acc,cur) => acc+=cur);
let findArr = [...tbodyCheck].map(ele=>ele.checked === true);
// console.log(findArr);
let findArrFalse = findArr.find(ele=>ele === false);
// 如果findArrFlase里有false,则全选框checked = false
if(findArrFalse === false){
checkAll.checked = false;
}else{
checkAll.checked = true;
}
});