js简易购物车

本文介绍如何使用JavaScript实现一个基本的购物车功能,包括添加商品、删除商品和计算总价等操作。通过实例代码讲解关键逻辑,适合初级开发者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        table,
        td {
            border: 1px solid black;
            border-collapse: collapse;
        }

        table {
            width: 980px;
            text-align: center;
            margin: 0 auto;
        }

        tr {
            height: 30px;
            line-height: 30px;
        }

        thead {
            font-weight: bold;

        }

        input[type=text] {
            width: 40px;
            height: 28px;
            text-align: center;
            border: 1px solid #A9A9A9;
        }

        tr td:nth-child(1) {
            width: 400px;
        }

        .showNull {
            display: none;
        }

        tbody>tr>td:nth-child(5) span {
            border: 1px solid #A9A9A9;
            height: 30px;
            display: inline-block;
            vertical-align: middle;
            width: 25px;
            user-select: none;
            cursor: pointer;
        }

        tbody>tr>td:nth-child(5) span:nth-child(1) {
            border-right: 0;
        }

        tbody>tr>td:nth-child(5) span:nth-child(3) {
            border-left: 0;
        }
    </style>
</head>

<body>
    <div id="showNull" class="showNull">
        购物车空空如也
    </div>
    <table id="shopCar">
        <caption>
            <h3>购物车</h3>
        </caption>
        <thead>
            <tr>
                <td>商品名</td>
                <td>原价</td>
                <td>优惠价</td>
                <td>打折</td>
                <td>数量</td>
                <td>删除</td>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>攀高搓背按摩器(蓝色) 定制版</td>
                <td><span>258.00</span></td>
                <td><span>129.00</span></td>
                <td>5.0折</td>
                <td><span>-</span><input type="text" value="1"><span>+</span></td>
                <td><a href="" class="deleteA">删除</a></td>
            </tr>
            <tr>
                <td>郝斌美国口语-美国口语成功训练系统(MP3)</td>
                <td><span>480.00</span></td>
                <td><span>292.90</span></td>
                <td>6.0折</td>
                <td><span>-</span><input type="text" value="2"><span>+</span></td>
                <td><a href="" class="deleteA">删除</a></td>
            </tr>
            <tr>
                <td>简 奥斯丁全集(DVD-9) (增BBC产品目录)</td>
                <td><span>138.00</span></td>
                <td><span>103.90</span></td>
                <td>8.0折</td>
                <td><span>-</span><input type="text" value="1"><span>+</span></td>
                <td><a href="" class="deleteA">删除</a></td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td>应付金额:</td>
                <td colspan="2"></td>

                <td>节省金额:</td>
                <td colspan="2"></td>

            </tr>
        </tfoot>
    </table>
    
    <script>
        // 获取到表格元素节点
        var shopCar = document.getElementById("shopCar");
        // 获取得到tbody的节点
        var tbodyEle = shopCar.tBodies[0];//一个页面中可以有多个tbody
        // console.log(tbodyEle)
        // 获取到tbody的所有的行
        var tbodyRows = tbodyEle.rows;
        // console.log(tbodyRows);//HTMLCollection(3) [tr, tr, tr]

        // 获取得到tfoot元素的节点
        var tfootEle = shopCar.tFoot;
        // 获取到tfoot的行
        var tfootRows = tfootEle.rows[0];
        // 获取到tfoot行内的所有单元格
        var tfootCells = tfootRows.cells;
    

        // 计算应付的金额  和  优惠的金额  封装到一个函数的内部
        function getPay(){
            //  声明两个变量用来存储应付的金额和优惠的金额
            var paySum=0;
            var originalSum=0;
            // 计算应付金额需要获取到每一行的第二个单元格
            for(var i=0;i<tbodyRows.length;i++){
                // 获取到tbody的每一行
                var row=tbodyRows[i];
                // 获取当前行的单元格
                var rowcells=row.cells;

                // 获取到原价所在的单元格
                var originalTd=rowcells[1];
                // 获取原价所在单元格的span
                // 通过标签名获取元素的节点是一个html collection
                var originalSpan = originalTd.getElementsByTagName("span")[0];
                // 获取原价
                var originalPrice=parseFloat(originalSpan.innerText);
                // console.log(originalPrice);

                 // 获取到优惠价所在的单元格
                 var disTd=rowcells[2];
                // 获取优惠价所在单元格的span
                var disSpan = disTd.getElementsByTagName("span")[0];
                // 获取优惠价
                var disPrice=parseFloat(disSpan.innerText);
                // console.log(disPrice);
                
                // 获取得到数量所在的单元格
                var countTd=rowcells[4];
                // 获取得到当前单元格所在的input框
                var countInput=countTd.getElementsByTagName("input")[0]; 
                // 获取数量  数量是在input元素节点的属性value中存储的
                var count = parseFloat(countInput.value);
                // console.log(count);

                // 计算得到应付金额
                paySum += disPrice * count;

                // 计算得到原本金额
                originalSum += originalPrice * count;
            }
            // 将已经计算好的金额分别添加到tfoot行中的  第二个单元格和第四个单元格中
            tfootCells[1].innerText="¥"+paySum.toFixed(2);
            tfootCells[3].innerText="¥"+(originalSum - paySum).toFixed(2);
        }
        getPay();
        
        // 当修改输入框的值得时候,重新计算,对输入得值进行判断
        // 获取到所有的输入框
        var inputs = shopCar.getElementsByTagName("input");
        // 需要给每个输入框都添加事件  获取焦点时对值进行修改
        // 失去焦点时对改过的值进行校验  如果是数字则显示  如果不是数字则改为原来的数值
        
        // 先获取到每个input输入框
        for(var i=0;i<inputs.length;i++){
            var ip=inputs[i];
            // 给每个input输入框添加获取焦点事件和失去焦点的事件
            ip.onfocus=function(){
                // 这时需要添加自定义属性用来存储改变的input输入框的值
                // 获取焦点时的值是当前的值  
                var val=this.value;
                // 添加自定义属性val  将值赋值给它
                this.setAttribute("val",val);
            }
            // 给每个input输入框添加失去焦点的事件
            ip.onblur=function(){
                // 判断修改过的值是否符合要求
                 var v=Number(this.value);
                 if(isNaN(v)){
                    //  如果这个值不是NaN  获取这个自定属性的值并且赋值给当前输入框的value属性
                    // 显示在输入框内
                     this.value=this.getAttribute("val")
                 }
                 else{
                    //  再次调用计算的函数  计算修改后的值
                    getPay();
                 }
                 
            }
                
        // 当点击input输入框前边的减号和后边的加号时可以对输入框中的值进行加减
        // 这时需要给input输入框的前边添加点击事件  点击的时候可以递减
        // 需要获取到input输入框的前一个兄弟节点
        // 调用已经封装好的获取前一个兄弟节点的函数
        var previousSpan=getPreviousElementSibling(ip);
        // console.log(previousSpan);
        previousSpan.onclick=function(){
            // 获取当前的输入框的值
            
            // 获取当前减号的下一个节点input输入框
            var input=getNextElementSibling(this);
            // 如果当前输入框的值等于1则将其返回
            if(input.value==="1"){
                return;
            }else{
                // 如果不等于1就递减
                input.value--;
            }
            // 再次计算改变数值后的值调用函数
            getPay();
        }
        // 给下一个兄弟节点加号添加点击事件
        var nextSpan=getNextElementSibling(ip);
        nextSpan.onclick=function(){
            // 获取当前输入框的值
            var input=getPreviousElementSibling(this);
            // 点击时将其累加
            input.value++;
            getPay();
        }
        }
        // 获取到所有删除的单元格的节点 当点击这个单元格的时候需要移除对应的行
        var deleteAs=document.getElementsByClassName("deleteA");
        // 给每一个添加点击事件
        for(var i=0;i<deleteAs.length;i++){
            deleteAs[i].onclick=function(){
                var t=confirm("是否删除当前商品");
                if(t){
                    // 获取到当前单元格的父节点的父节点就是当前单元格所对应的行
                    var deletetr=this.parentNode.parentNode;
                    // 用父节点tbody删除子节点行
                    tbodyEle.removeChild(deletetr);
                    // 调用函数计算删除后的值
                    getPay();
                }
                // 清除超链接的默认行为
                return false;
            }
        }


        

        // nextElementSibling兼容性处理
function getNextElementSibling(element) {
    var el = element;
    while (el = el.nextSibling) {
        if (el.nodeType === 1) {
            return el;
        }
    }
    return null;
}

// previousElementSibling兼容性处理
function getPreviousElementSibling(element) {
    var el = element;
    while (el = el.previousSibling) {
        if (el.nodeType === 1) {
            return el;
        }
    }
    return null;
}
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sclience_kang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值