批改状态:合格
老师批语:
以课堂案例为基础,更新以下内容
商品列表 DOM 结构由脚本动态生成
修复课堂案例中点击复选框后再改变数量时数据不准确的问题
// (一) 从购物车模块中获取数据import carts from './carts.js'// (二) 根据 carts.data 生成对应的商品列表(<tr>),同时将商品数据渲染到页面const cartsBody = document.querySelector('.carts-body')carts.data.forEach((item) => {// 创建临时 elemFlagconst elemFlag = document.createDocumentFragment()// 每条数据创建一个<tr>元素const trElem = document.createElement('tr')trElem.classList.add('item')// 为<tr>创建对应的单元格<td>// 第一个<td>: checkbox// <td><input type="checkbox" name="" class="check" checked /></td>const tdElem = document.createElement('td')const checkElem = document.createElement('input')checkElem.type = 'checkbox'checkElem.name = ''checkElem.classList.add('check')checkElem.checked = truetdElem.append(checkElem)trElem.append(tdElem)// 将当前data数据放置到对应的单元格<td>for (let key in item) {const tdElem = document.createElement('td')if (key === 'num') {// <td><input type="number" name="" class="num" value="1" min="1" /></td>const numInput = document.createElement('input')numInput.type = 'number'numInput.name = ''numInput.classList.add(key)numInput.value = item[key]numInput.min = '1'tdElem.append(numInput)trElem.append(tdElem)} else {tdElem.classList.add(key)tdElem.append(item[key])trElem.append(tdElem)}}elemFlag.append(trElem)cartsBody.append(elemFlag)})// (三) 将总数量、总金额渲染到页面中// 1. 总数量 carts.totalconst total = document.querySelector('.carts-foot .total')total.textContent = carts.total// 2. 总金额 carts.totalMoneyconst totalMoney = document.querySelector('.carts-foot .total-money')totalMoney.textContent = carts.totalMoney
思路:
html文件中的脚本
import * as calc from './calc.js'// (四) 获取购物车商品的复选框、数量、单价、金额构成的 NodeList// 单价(NodeList),用于数量改变时计算金额const prices = document.querySelectorAll('.carts-body .price')// 数量(NodeList => Array)const nums = document.querySelectorAll('.carts-body .num')let numsArr = [...nums]// 金额数组(NodeList => Array)const monies = document.querySelectorAll('.carts-body .money')let moniesArr = [...monies]// check数组(NodeList),用于判断是否选中const checks = document.querySelectorAll('.carts-body .check')// (五) 为数量控件添加 change 事件nums.forEach(function (num, index) {num.onchange = function () {// 1. 计算当前商品金额 = 数量 * 单价// 未选择时也可用更改数量及对应的金额,只是不计入汇总monies[index].textContent = (num.value * prices[index].textContent).toString()// 2. 计算总数量并渲染到页面total.textContent = calc.calcTotalNum(numsArr)// 3. 计算总金额并渲染到页面totalMoney.textContent = calc.calcTotalMoney(moniesArr)}})// (六) 复选框// 全选按钮const checkAll = document.querySelector('.check-all')// 为全选添加changecheckAll.onchange = function () {// 遍历所有商品的状态,并将当前全选按钮的状态赋值给它checks.forEach(check => check.checked = checkAll.checked)// 根据所有商品的全选/全不选状态,更新 数量数组 numsArr 和 金额数组 moniesArr// 全不选if (false === this.checked) {// 删除数量数组中的所有数据,重新计算总数量并渲染到页面for (let i = 0; i < numsArr.length; i++) {delete numsArr[i]}total.textContent = calc.calcTotalNum(numsArr)// 删除金额数组中的所有数据,重新计算总数量并渲染到页面for (let i = 0; i < moniesArr.length; i++) {delete moniesArr[i]}totalMoney.textContent = calc.calcTotalMoney(moniesArr)} else {// 全选// 从 NodeList 中重新获取数量数组,重新计算总数量并渲染到页面numsArr = [...nums]total.textContent = calc.calcTotalNum(numsArr)// 从 NodeList 中重新获取金额数组,重新计算总金额并渲染到页面moniesArr = [...monies]totalMoney.textContent = calc.calcTotalMoney(moniesArr)}}// 遍历每个商品的复选框,并添加change,动态的计算相关数据checks.forEach(function (check, index) {check.onchange = function () {// 根据所有商品的复选框的状态,来动态的设置全选checkAll.checked = [...checks].every(check => check.checked)// 如果商品未选中,从数量数组和金额数组中减去相应的数据,并重新计算总数量和总金额// 如果商品选中,从数量数组和金额数组中添加相应的数据,并重新计算总数量和总金额if (false === check.checked) {// 将当前数量对应的<input>元素,从数量数组中删除,重新计算总数量并渲染到页面delete numsArr[index]total.textContent = calc.calcTotalNum(numsArr)// 将当前金额对应的<td>元素,从金额数组中删除,重新计算总金额并渲染到页面delete moniesArr[index]totalMoney.textContent = calc.calcTotalMoney(moniesArr)} else {// 获取当前商品对应的行元素<tr>const curTr = this.parentElement.parentElement// 获取当前商品金额对应的单元格元素<td>const curMoney = curTr.lastElementChild// 获取当前商品数量对应的<input>元素const curNum = curMoney.previousElementSibling.firstElementChild// 将当前数量对应的<input>元素,添加到数量数组,重新计算总数量并渲染到页面numsArr[index] = curNumtotal.textContent = calc.calcTotalNum(numsArr)// 将当前金额对应的<td>元素,添加到金额数组,重新计算总金额并渲染到页面moniesArr[index] = curMoneytotalMoney.textContent = calc.calcTotalMoney(moniesArr)}}
calc.js 模块
export function calcTotalNum(arr){let tempTotal = 0arr.forEach((item) => tempTotal += parseInt(item.value))return tempTotal}export function calcTotalMoney(arr) {let tempTotalMoney = 0arr.forEach((item) => tempTotalMoney += parseInt(item.textContent))return tempTotalMoney}

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号