JavaScript实现购物车自动计算
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>购物车全选</title>
<style>
table {
border-collapse: collapse;
width: 90%;
text-align: center;
margin: auto;
}
table caption {
margin-bottom: 15px;
font-size: 1.5rem;
}
table th,
table td {
/* border: 1px solid #888; */
border-bottom: 1px solid #888;
padding: 5px;
}
table thead tr:first-of-type {
background-color: rgb(222, 222, 222);
}
/* 隔行变色: 偶数行 */
/* table tbody tr:nth-of-type(even) {
background-color: rgb(240, 240, 240);
} */
table input[type="checkbox"] {
width: 20px;
height: 20px;
}
button {
width: 150px;
height: 30px;
outline: none;
border: none;
background-color: #f40;
color: white;
letter-spacing: 5px;
}
button:hover {
background: #999;
background-color: coral;
cursor: pointer;
}
.my {
color: #f40;
font-weight: 700;
}
</style>
</head>
<body>
<table>
<caption class="my">
购物车
</caption>
<thead>
<tr>
<th>
<input
type="checkbox"
name="checkAll"
id="check-all"
checked
/><label for="check-all"></label>
</th>
<th>ID</th>
<th>品名</th>
<th>单位</th>
<th>单价/元</th>
<th>数量</th>
<th>金额/元</th>
</tr>
</thead>
<tbody id="aaa">
<tr>
<td>
<input type="checkbox" name="itemId" value="SN-1010" checked />
</td>
<td>SN-1010</td>
<td>MacBook Pro电脑</td>
<td>台</td>
<td>18999</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SN-1020" checked />
</td>
<td>SN-1020</td>
<td>iPhone手机</td>
<td>部</td>
<td>4999</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SN-1030" checked />
</td>
<td>SN-1030</td>
<td>智能AI音箱</td>
<td>只</td>
<td>399</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SN-1040" checked />
</td>
<td>SN-1040</td>
<td>SSD移动硬盘</td>
<td>个</td>
<td>888</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
<tr>
<td>
<input type="checkbox" name="itemId" value="SN-1050" checked />
</td>
<td>SN-1050</td>
<td>黄山毛峰</td>
<td>斤</td>
<td>999</td>
<td>
<input type="number" name="counter" value="1" min="1" step="1" />
</td>
<td></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="font-weight: 700;">总计:</td>
<td id="total-num" class="my">0</td>
<td id="total-price" class="my">0</td>
</tr>
</tfoot>
</table>
<div style="width: 90%; margin: 10px auto;">
<button style="float: right; width: 100px;">结算</button>
</div>
<script>
// 全选复选框
var checkAllBtn = document.querySelector("#check-all");
// 单个复选框
var checkItemBtns = document.getElementsByName("itemId");
// 获取所有单价(单价列)
var prices = document.querySelectorAll("tbody > tr > td:nth-of-type(5)");
// 获取所有数量INPUT框
var numbers = document.querySelectorAll("input[type=number]");
// 获取所有金额(最后一列)
var sumPrices = document.querySelectorAll("tbody > tr > td:nth-of-type(7)");
// 商品数量(单条): 数组
var number = [];
// 商品金额: 数组
var Price = [];
// 商品总数量var
var totalNum = 0;
// 商品总金额
var totalPrices = 0;
// 载入时计算商品数量/单价/总价-----------------------------------
getPrices(); //获取每行单价
getTotalNum(numbers); //获取第5列商品数量
getTotalPrices(sumPrices); //获取第7列商品总价
//获取商品总数量(数量列相加)-------------------------------------
function getTotalNum(numbers) {
totalNum = 0;
numbers.forEach(function (num) {
var chk = num.parentNode.parentNode.children[0].childNodes[1];
if (chk.checked) totalNum += parseInt(num.value);
});
document.querySelector("#total-num").innerText = totalNum;
}
//每行单价------------------------------------------------------
function getPrices() {
var index = 0;
checkItemBtns.forEach(function (ev) {
sumPrices[index].innerText =
parseInt(numbers[index].value) * parseInt(prices[index].innerText);
index++;
});
}
//获取总价格(最后一列相加)--------------------------------------
function getTotalPrices(sumPrices) {
//总价先清零,避免累加
totalPrices = 0;
// 遍历最后一列
sumPrices.forEach(function (price) {
// 获取选中状态
var chk = price.parentNode.children[0].childNodes[1];
if (chk.checked) {
// 商品选中总价格才相加(并设置背景高亮)
totalPrices += parseInt(price.innerText);
chk.parentNode.parentNode.style.cssText = "background:#fff8e1";
} else {
// 商品未选中取消背景高亮
chk.parentNode.parentNode.style.cssText = "background:#fff";
}
});
// 更新总价格
document.querySelector("#total-price").innerText = totalPrices;
}
// 给表头的全选按钮添加事件--------------------------------------
checkAllBtn.addEventListener("change", allChange, false);
function allChange(ev) {
// 遍历每个商品复选框,根据全选状态控制每个商品复选框状态
checkItemBtns.forEach(function (btn) {
btn.checked = ev.target.checked;
});
getTotalNum(numbers); //更新商品总数量
getTotalPrices(sumPrices); //更新商品总金额
}
//每行的复选框添加监听事件---------------------------------------
checkItemBtns.forEach(function (btn) {
// 根据每个复选框的状态,控制全选的状态
btn.addEventListener("change", itemChange, false);
});
function itemChange(btn) {
var i = 0;
//循环每个复选框,得到选中状态复选框数量
checkItemBtns.forEach(function (btn) {
if (btn.checked) i++;
});
// 设置全选按钮的状态(如果商品的复选框数量等于总的商品条目数,就将全选选中/取消)
checkAllBtn.checked = i === checkItemBtns.length;
getTotalNum(numbers); //更新商品总数量
getTotalPrices(sumPrices); //更新商品总金额
}
//循环每个INPUT并添加监听事件,当商品数量发生变化,重新计算价格------
numbers.forEach(function (btn) {
btn.addEventListener(
"input",
function () {
getTotalNum(numbers); //更新商品总数量
getPrices(); //获取每行单价
getTotalPrices(sumPrices); //更新商品总金额
},
false
);
});
</script>
</body>
</html>
总结
- 本以为很简单就实现了,整体思路没弄清楚,要做一个完美购物车案例,还是有难度的。