功能思路分析
购物车功能包括添加商品(需判断购物车是否为空及商品是否已存在),调整商品数量(包括增加和减少,并考虑库存限制),计算商品总价(单个商品及购物车内所有商品),删除商品(单个或多个选中商品),以及全选和反选功能来批量操作商品,并计算选中商品的总价。
HTML结构搭建
- 字段集(
<fieldset>) :用于将购物车相关的元素分组,提高可读性。- 商品信息输入:包含三个
<input>元素,分别用于输入商品名称、单价和数量。- 添加按钮:一个
<button>元素,用户点击后将触发添加商品到购物车的操作。- 商品列表展示:一个
<table>元素,用于展示购物车中的商品列表。- 全选复选框:在表格头部,用于全选或取消全选所有商品。
- 删除按钮:用于删除选中的商品。
- 总价显示:显示购物车中所有商品的总价。
<fieldset id="">
<legend>购物车</legend>
<div id="">
商品名称:<input type="text" id="goodsName" /> 商品单价:<input
type="text"
id="goodsPrice"
/>
商品数量:<input type="text" id="goodsNum" />
<button onclick="addgoods()">加入购物车</button>
</div>
<table width="800px" border="1">
<thead>
<tr>
<th>
全选
<input
id="chkAll"
onclick="checkAll(this)"
type="checkbox"
/>
</th>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>商品总价</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tbody"></tbody>
</table>
<button id="aaaaa" onclick="delCheckGoods()">删除选中商品</button>
总价:<span id="zongjia">0</span>
</fieldset>
CSS样式(可选)
- 整体布局调整: 字段集(
<fieldset>)宽度和居中- 表格行样式统一: 表格行(
<tr>)高度和文本对齐- 特定元素样式调整: 删除按钮(#aaaaa)位置调整
<style type="text/css">
fieldset {
width: 800px;
/*text-align: center;*/
margin: auto;
}
tr {
height: 30px;
text-align: center;
}
#aaaaa {
margin-right: 540px;
}
</style>
JavaScript交互
1.商品添加逻辑
add函数:负责将新商品添加到购物车表格中。
- 使用字符串拼接法创建一个新的表格行(
<tr>),包含商品的复选框、名称、单价、数量操作按钮和总价,以及删除按钮。- 动态创建
<input>、<button>等HTML元素,并设置它们的事件处理函数和属性。- 将拼接好的字符串转换为DOM元素,并添加到
tbody中。
addgoods函数:负责在添加新商品时检查购物车中是否已存在相同商品。
- 如果购物车为空或没有相同商品,直接调用
add函数添加新商品。- 如果存在相同商品,则增加该商品的数量,并更新总价。
2. 数量调整逻辑
btnJia函数:加号按钮的事件处理函数,用于增加商品数量。
- 更新数量输入框的值,并重新计算总价。
- 调用
jisuan函数更新总价显示。
btnJian函数:减号按钮的事件处理函数,用于减少商品数量。
- 检查数量是否大于1,避免数量为0。
- 更新数量输入框的值,并重新计算总价。
- 调用
jisuan函数更新总价显示。3. 商品删除逻辑
delBtn函数:删除按钮的事件处理函数,用于删除单个商品。
- 直接删除包含删除按钮的表格行(
<tr>)。- 调用
jisuan函数更新总价显示。
delCheckGoods函数:用于删除选中的商品。
- 遍历所有复选框,如果选中,则删除对应的表格行。
- 调用
jisuan函数更新总价显示。4. 全选/反选逻辑
checkAll函数:全选复选框的事件处理函数。
- 设置所有商品复选框的状态与全选框一致。
- 调用
jisuan函数更新总价显示。
fanChk函数:反选复选框的事件处理函数。
- 检查所有复选框是否全部选中,以决定全选框的状态。
- 调用
jisuan函数更新总价显示。5. 总价计算逻辑
jisuan函数:用于计算并更新总价显示。
- 遍历所有复选框,如果选中,则累加其总价。
- 更新页面上的总价显示。
6. 数量输入逻辑
bbb函数:数量输入框失去焦点事件的处理函数。
- 更新对应商品的总价。
- 调用
jisuan函数更新总价显示。
<script type="text/javascript">
//① 先写普通新增
function add() {
//字符串拼接法:
var str = "";
//添加第1个td
str +=
"<td><input class='check' type='checkbox' onclick='fanChk()'></td>";
//添加第2个td
str += "<td class='gname'>" + goodsName.value + "</td>";
//添加第3个td
str += "<td>" + goodsPrice.value + "</td>";
//添加第4个td
str +=
"<td><button onclick='btnJia(this)'>+</button><input onblur='bbb(this)' type='number' value='" +
goodsNum.value +
"'/><button onclick='btnJian(this)'>-</button></td>";
//添加第5个td
str += "<td>" + goodsPrice.value * goodsNum.value + "</td>";
//添加第6个td
str += "<td><button onclick='delBtn(this)'>删除</button></td>";
var tr = document.createElement("tr");
tr.innerHTML = str;
tbody.appendChild(tr);
}
//② 条件新增
function addgoods() {
//如果没有:直接调用添加方法
//如果tbody中子节点的长度为0 说明没有子节点,就是说购物车为空,直接添加
if (tbody.children.length == 0) {
add();
} else {
/*如果有商品:
再判断该商品在购物车中是否存在?
如何判断?使用商品名称判断。
*/
var gNameArr = document.getElementsByClassName("gname");
//借助第三方变量 给定一个状态
var state = false; //假设没有相同商品
for (var i = 0; i < gNameArr.length; i++) {
//如果有相同商品
if (gNameArr[i].innerText == goodsName.value) {
//如果有相同商品就让 state==true
state = true;
break;
}
}
//只有当循环执行完毕后,确定没有相同的商品了,此时才可以add();
if (state == true) {
//有相同商品
//将数量相加
//问题:如何拿到当前这个相同的商品在购物车中的数量呢?
var tdEleArr = gNameArr[i].parentNode.children;
tdEleArr[3].children[1].value =
Number(tdEleArr[3].children[1].value) +
Number(goodsNum.value);
//计算总价
tdEleArr[4].innerText =
tdEleArr[3].children[1].value * goodsPrice.value;
} else {
//没有相同商品
add();
}
}
}
//加号按钮
function btnJia(btn) {
//数量++
//btn.nextElementSibling.value++;
//计算总价
btn.parentNode.nextElementSibling.innerText =
btn.parentNode.previousElementSibling.innerText *
++btn.nextElementSibling.value;
jisuan();
}
//减号按钮
function btnJian(btn) {
if (btn.previousElementSibling.value == 1) {
alert("不能在减了呦!");
} else {
//计算总价
btn.parentNode.nextElementSibling.innerText =
btn.parentNode.previousElementSibling.innerText *
--btn.previousElementSibling.value;
}
jisuan();
}
//删除单个商品
function delBtn(btn) {
//删除当前点击的删除按钮的父节点的父节点 刚好就是tr
btn.parentNode.parentNode.remove();
jisuan();
}
//删除选中商品
function delCheckGoods() {
//var checkArr = document.querySelectorAll("tbody .check");
var checkArr = document.getElementsByClassName("check");
/*for(var i=0;i<checkArr.length;i++){
if(checkArr[i].checked==true){
checkArr[i].parentNode.parentNode.remove();
}
}*/
for (var i = checkArr.length - 1; i > 0; i--) {
if (checkArr[i].checked == true) {
checkArr[i].parentNode.parentNode.remove();
}
}
jisuan();
}
//全选/反选
//全选:
function checkAll(chk) {
var checkArr = document.querySelectorAll("tbody .check");
for (var i = 0; i < checkArr.length; i++) {
checkArr[i].checked = chk.checked;
}
jisuan();
}
//反选:
function fanChk() {
//alert(111)
var checkArr = document.querySelectorAll("tbody .check");
var state = true; //假设不存在没有被选中的复选框
for (var i = 0; i < checkArr.length; i++) {
if (checkArr[i].checked == false) {
state = false;
break;
}
}
if (state == true) {
//alert(checkAll);
//让全选框变成选中状态
chkAll.checked = true;
} else {
chkAll.checked = false;
}
jisuan();
}
//封装一个计算总价的函数
function jisuan() {
var sum = 0;
var checkArr = document.querySelectorAll("tbody .check");
for (var i = 0; i < checkArr.length; i++) {
if (checkArr[i].checked == true) {
sum += Number(
checkArr[i].parentNode.parentNode.children[4]
.innerText
);
}
}
zongjia.innerText = sum + "元";
}
//购物车中数量输入框的失去焦点事件
function bbb(inp) {
inp.parentNode.nextElementSibling.innerText =
inp.value * inp.parentNode.previousElementSibling.innerText;
jisuan();
}
</script>
最终效果
1.默认效果图
2.加入购物车(没有商品)
3.加入购物车(有商品)
4.多次重复加入购物车
5.增加或减少商品数量
6.删除购物车中的商品
7.全选和反选
小结:
- 首页理解购物车功能是实现过程
- 再进行搭建HTML页面
- 再通过CSS进行样式设计
- 最后使用JavaScript完成核心交互功能的实现
你的点赞就是我持续更新最大的动力!