使用原生JavaScript实现购物车的功能模块

278 阅读6分钟

功能思路分析

购物车功能包括添加商品(需判断购物车是否为空及商品是否已存在),调整商品数量(包括增加和减少,并考虑库存限制),计算商品总价(单个商品及购物车内所有商品),删除商品(单个或多个选中商品),以及全选和反选功能来批量操作商品,并计算选中商品的总价。

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完成核心交互功能的实现

你的点赞就是我持续更新最大的动力!