超详细购物车案例js实现购物车下【2021.10.11】

这篇博客详细介绍了如何实现一个购物车的功能,包括全选、反选、单选按钮的逻辑,数量文本框的控制,加减按钮的操作,以及删除商品的功能。通过JavaScript和DOM操作,实现了选中状态的切换、背景颜色的变化、小计和总价的实时计算。此外,还涉及到了动态创建元素和事件监听,以及商品列表的更新和总价的刷新。
摘要由CSDN通过智能技术生成

一、前言

        本文所用的代码是之前看一个大大所写的,忘记大大名字了,侵权立删。实现购物车的方法有很多,我们不应该把重心放在代码上,而是应该放在功能上和逻辑上,这样再复杂的项目,也能从众多功能中一步一步下手。不会代码我们可以去查,直到实现功能为止。

二、功能

1.全选按钮

  • 点击后反选按钮的状态改为未选中状态
  • 判断点击后是否为选中状态,是则选中所有单选按钮并通过改变classname从而改变背景颜色,否则取消所有单选按钮
//全选
    var checkAll = document.getElementsByClassName("checkAll")[0];
    var check = document.getElementsByClassName("check");//集合
    var bEle = document.getElementsByClassName("b-ele");
    var allPrice = document.getElementsByClassName("allPrice")[0];
    checkAll.onclick = function () {
        for (var i = 0; i < check.length; i++) {
            reverseCheck.checked = false
            if (checkAll.checked == true) {
                check[i].checked = true;
                bEle[i].className = "b-ele chooseEle";
            } else {//点击全选按钮之后,是未选中状态,则将check状态改为未选中
                bEle[i].className = "b-ele";///通过不同的命名改变背景,好方法
                check[i].checked = false;
            }
        }
    };

2.反选按钮

  • 点击后通过逻辑运算符!改变单选按钮的选中状态
  • 判断点击后否为选中状态,是则改背景,否则让全选按钮为非选中状态且改回背景
//反选
    var reverseCheck = document.getElementsByClassName("reverseCheck")[0];
    reverseCheck.onclick = function () {
        //输入数量
        for (var i = 0; i < check.length; i++) {
            check[i].checked = !check[i].checked;//直接将所有的check状态反选
            if (check[i].checked == false) {//点击之后是非选中状态,通过class改背景
                bEle[i].className = "b-ele";
                checkAll.checked = false;//将全选按钮改为非选中
            } else {
                bEle[i].className = "b-ele chooseEle";
            }
        }
    };

3.单选按钮

  • 点击后是选中状态则改变背景色
  • 非选中状态则改回背景色,并取消全选按钮的选中状态
//单选
    for (var i = 0; i < bEle.length; i++) {
        check[i].checkValue = i;
        check[i].onclick = function () {
            console.log(this.checked)
            if (this.checked == true) {//点击后是选中状态的话
                console.log(this.className)
                bEle[this.checkValue].className = "b-ele chooseEle";//通过this的i等于bEle的索引值来改变classname
            } else {
                checkAll.checked = false;//点击后是没选中状态,让背景消失
                bEle[this.checkValue].className = "b-ele"
            }
        }
    }

4.数量文本框

  • 可以用键盘上的数字和删除按钮backsp进行操作,其它按钮显示NaN(不是数值)
  • 当文本框值为0或空值时,让文本框的值改为1
  • 文本框中的值为大于1的数字时,计算小计的值,刷新总价格的值
//对文本框的操作
        for (var i = 0; i < bEle.length; i++) {
            bCountInput[i].countNum = i;
            bCountInput[i].onkeydown = function (e) {
                if ((e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == 8||(e.keyCode >= 96 && e.keyCode <= 105)) {//keyCode是键码值,8是backsp,48=0,57=9,是横着的那排数字
                } else {
                    return false//nan
                }
            };
            bCountInput[i].onblur = function () {
                if (this.value == "") {
                    this.value = 1;//空值强改1并刷新小计
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";
                }
            };
            bCountInput[i].onkeyup = function () {
                if (this.value == "") {//this指向调用它的对象就是文本框拉
                    bTotal[this.countNum].innerHTML = "0¥";//空白
                } else if (this.value == 0) {
                    this.value = 1;//如果为0,强行改为1,并刷新小计
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥"
                } else {
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";//首先文本框只能输入数字和空值,然后检测文本框为0或为空值时改为1且刷新小计
                }
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价格
            }
        }

5.控制数量的加减按钮

  • 点击减少按钮,先判断是否为1,为1则提示不能减了1,不为1则做自减计算小计刷新总价
  • 点击加按钮,做自加,计算小计刷新总价
//数量进行加减
        allPrice.innerHTML = cacAllPrice(bTotal)+"¥";//先把所有小计的函数给写出来
        for (var i = 0; i < bEle.length; i++) {
            buttonSub[i].countNum = i;
            buttonSub[i].onclick = function () {
                if (bCountInput[this.countNum].value == 1) {//数量为1时提示
                    alert("该宝贝不能减少了噢!")
                } else {
                    var value = --bCountInput[this.countNum].value;//数量减一
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//括号里的是形参,计算小计
                    allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//重新刷新总价
                }
            };
            buttonAdd[i].countNum = i;
            buttonAdd[i].onclick = function () {
                var value = ++bCountInput[this.countNum].value;//数量加一
                bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//计算小计
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"
            }
        }

6.删除按钮

  • 使对应的商品从列表中删除
  • 重新给所有对象加索引值
  • 刷新总价
//删除元素
        console.log(bEle.length);
        for (var i = 0; i < bEle.length; i++) {
            eleDelete[i].value = i;
            eleDelete[i].onclick = function () {
                bList.removeChild(bEle[this.value]);//删除节点
                for(var k = 0;k<bEle.length;k++){
                    //重新给所有对象的value/countNum索引值
                    eleDelete[k].value = k;//对删除按钮重新上值
                    buttonSub[k].countNum=k;//对数量加重新上编号(索引)
                    bCountInput[k].countNum=k;//文本框
                    buttonAdd[k].countNum=k;
                }
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价
            }
        }
    }

7.小计

  • 设置形参,通过价格=单价*数量得到小计
//计算小计
    function cacTotal(index, priceObj, value) {//形参
        return parseFloat(priceObj[index].innerHTML) * parseInt(value);//括号里是单价*数量,parseFloat()返回从位置0开始查看每一个字符,直到找到第一个非有效字符,然后把之前的字符串转换为数字
    }

8.总价

  • .遍历所有的小计,挨个相加得到总价
//计算总价
    function cacAllPrice(bTotal) {
        var totalPrice=0;//随便定义一个变量为0
        for(var i=0;i<bTotal.length;i++){//遍历所有的小计
            totalPrice += parseFloat(bTotal[i].innerHTML)//加
        }
        return totalPrice;//返回总价格
    }

三、代码部分

.

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
            font-size: 14px;
        }

        .all {
            width: 1000px;
            margin: auto;
        }

        .b-top {
            display: flex;
            flex-direction: row;
            background: #ffe0cb;
            height: 30px;
            line-height: 30px;
        }

        .b-info {
            flex: 1;
            text-align: center;
        }

        .b-length {
            flex: 2;
        }

        .b-ele {
            display: flex;
            flex-direction: row;
            height: 70px;
            line-height: 70px;
            padding: 10px 0;
            border-bottom: 1px dashed silver;
        }

        .b-ele div {
            text-align: center;
        }

        .chooseEle {
            background: pink;
        }

        .b-button {
            color: blue;
            width: 60px;
            height: 25px;
            text-align: center;
            line-height: 25px;
            background: silver;
            border: none;
        }

        .b-count-button {
            width: 25px;
            height: 25px;
            border: none;
            color: blue;
            background: orange;
        }

        .b-count-input {
            border: none;
            height: 20px;
            width: 25px;
            outline: none;
            text-align: center;
        }

        img {
            width: 25px;
            height: 25px;
        }

        .b-display {
            display: flex;
            justify-content: space-between;
        }

        .b-display div {
            width: 120px;
            height: 40px;
            line-height: 40px;
        }

        .left {
            text-align: center;
        }

        .right button {
            width: 100%;
            height: 100%;
            background: red;
            color: white;
            text-align: center;
            border: none;
        }
    </style>
</head>
<body>
<div class="all">
    <div class="b-top">
        <div class="b-info">
            <input type="checkbox" class="checkAll"/>全选
        </div>
        <div class="b-info b-length">商品名称</div>
        <div class="b-info">图片</div>
        <div class="b-info">单价</div>
        <div class="b-info b-length">数量</div>
        <div class="b-info">小计</div>
        <div class="b-info">操作</div>
    </div>
    <div class="b-list"></div>
    <div class="b-display">
        <div class="left">
            <input type="checkbox" class="reverseCheck"/>反选
        </div>
        <div class="center">
            总价:<span class="allPrice">0¥</span>
        </div>
        <div class="right">
            <button>去结算></button>
        </div>
    </div>
</div>
</body>
<script>
    var cart = [
        {
            "id": "101321XNMNSDJYE6871DAS21",
            "name": "华为nova5 pro",
            "src": "./cartimage/415d8ef0da06eb00.png",
            "price": "1499",
            "totle": "1499",
            "num": 1
        },//数组字面量里面写入四个对象
        {
            "id": "101321XNMNSDJYE6871DAS21",
            "name": "华为nova5 pro",
            "src": "./cartimage/415d8ef0da06eb00.png",
            "price": "1599",
            "totle": "1599",
            "num": 1
        },
        {
            "id": "101321XNMNSDJYE6871DAS21",
            "name": "华为nova5 pro",
            "src": "./cartimage/415d8ef0da06eb00.png",
            "price": "1699",
            "totle": "1699",
            "num": 1
        },
        {
            "id": "101321XNMNSDJYE6871DAS21",
            "name": "华为nova5 pro",
            "src": "./cartimage/415d8ef0da06eb00.png",
            "price": "1799",
            "totle": "1799",
            "num": 1
        }
    ];//为购物车建立数组对象
    var bTop = document.getElementsByClassName("b-top")[0];//获取info信息栏
    var bList = document.getElementsByClassName("b-list")[0];//获取表单盒子
    //动态创建页面-创四个商品盒
    for (var i = 0; i < cart.length; i++) {//for循环 !!!!别用let声明,var可以重复声明,let不行
        var bEle = document.createElement("div");//创建一个div
        bEle.className = "b-ele";//div的classname
        bList.appendChild(bEle);//将新建的div放到list里面

        var bNode = document.createElement("div");//创
        bNode.className = "b-info";
        var bInput = document.createElement("input");//创建一个表单
        bInput.type = "checkbox";//类型为复选框
        bInput.className = "check";//classname
        bNode.appendChild(bInput);//将表单放在创建的div中
        bEle.appendChild(bNode);//将上面的div放到上上面的div中 

        var bNode = document.createElement("div");
        bNode.className = "b-info b-length";
        bNode.innerHTML = cart[i].name;//将name写进去
        bEle.appendChild(bNode);//继续放到bEle里面

        var bNode = document.createElement("div");
        bNode.className = "b-info";
        bNode.style.lineHeight = "80px"
        var bImg = document.createElement("img");//放照片
        bImg.src = cart[i].src;
        bNode.appendChild(bImg);
        bEle.appendChild(bNode);

        var bNode = document.createElement("div");
        bNode.className = "b-info b-price";
        bNode.innerHTML = cart[i]["price"] + "¥";//单价
        bEle.appendChild(bNode);

        var bNode = document.createElement("div");
        bNode.className = "b-info b-length";
        var bCountButtonSub = document.createElement("button");
        bCountButtonSub.className = "b-count-button buttonSub";
        bCountButtonSub.innerHTML = "-";
        var bCountInput = document.createElement("input");
        bCountInput.type = "text";
        bCountInput.className = "b-count-input";//数量文本框
        bCountInput.value = cart[i].num;
        var bCountButtonAdd = document.createElement("button");
        bCountButtonAdd.className = "b-count-button buttonAdd";//加减按钮
        bCountButtonAdd.innerHTML = "+";
        bNode.appendChild(bCountButtonSub);
        bNode.appendChild(bCountInput);
        bNode.appendChild(bCountButtonAdd);
        bEle.appendChild(bNode)

        var bNode = document.createElement("div");
        bNode.className = "b-info b-total";
        bNode.innerHTML = cart[i].totle + "¥";//小记
        bEle.appendChild(bNode);

        var bNode = document.createElement("div");
        bNode.className = "b-info";
        var bCountButton = document.createElement("button");//删除按钮
        bCountButton.className = "b-button eleDelete";
        bCountButton.innerHTML = "删除";
        bNode.appendChild(bCountButton)
        bEle.appendChild(bNode)
    }
    ;
    //全选
    var checkAll = document.getElementsByClassName("checkAll")[0];
    var check = document.getElementsByClassName("check");//集合
    var bEle = document.getElementsByClassName("b-ele");
    var allPrice = document.getElementsByClassName("allPrice")[0];
    checkAll.onclick = function () {
        for (var i = 0; i < check.length; i++) {
            reverseCheck.checked = false
            if (checkAll.checked == true) {
                check[i].checked = true;
                bEle[i].className = "b-ele chooseEle";
            } else {//点击全选按钮之后,是未选中状态,则将check状态改为未选中
                bEle[i].className = "b-ele";///通过不同的命名改变背景,好方法
                check[i].checked = false;
            }
        }
    };
    //反选
    var reverseCheck = document.getElementsByClassName("reverseCheck")[0];
    reverseCheck.onclick = function () {
        //输入数量
        for (var i = 0; i < check.length; i++) {
            check[i].checked = !check[i].checked;//直接将所有的check状态反选
            if (check[i].checked == false) {//点击之后是非选中状态,通过class改背景
                bEle[i].className = "b-ele";
                checkAll.checked = false;//将全选按钮改为非选中
            } else {
                bEle[i].className = "b-ele chooseEle";
            }
        }
    };
    //单选
    for (var i = 0; i < bEle.length; i++) {
        check[i].checkValue = i;
        check[i].onclick = function () {
            console.log(this.checked)
            if (this.checked == true) {//点击后是选中状态的话
                console.log(this.className)
                bEle[this.checkValue].className = "b-ele chooseEle";//通过this的i等于bEle的索引值来改变classname
            } else {
                checkAll.checked = false;//点击后是没选中状态,让背景消失
                bEle[this.checkValue].className = "b-ele"
            }
        }
    }
    window.onload = function (ev) {
        //

        var buttonSub = document.getElementsByClassName("buttonSub");//上面创建的数量减小按钮的合集哦
        var buttonAdd = document.getElementsByClassName("buttonAdd");//数量增加按钮
        var bCountInput = document.getElementsByClassName("b-count-input");//数量文本框
        var bEle = document.getElementsByClassName("b-ele");//信息盒的集合
        var bTotal = document.getElementsByClassName("b-total");//小计
        var bPrice = document.getElementsByClassName("b-price");//单价
        var eleDelete = document.getElementsByClassName("eleDelete");//删除
        var allPrice = document.getElementsByClassName("allPrice")[0];//总价格
        //数量进行加减
        allPrice.innerHTML = cacAllPrice(bTotal)+"¥";//先把所有小计的函数给写出来
        for (var i = 0; i < bEle.length; i++) {
            buttonSub[i].countNum = i;
            buttonSub[i].onclick = function () {
                if (bCountInput[this.countNum].value == 1) {//数量为1时提示
                    alert("该宝贝不能减少了噢!")
                } else {
                    var value = --bCountInput[this.countNum].value;//数量减一
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//括号里的是形参,计算小计
                    allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//重新刷新总价
                }
            };
            buttonAdd[i].countNum = i;
            buttonAdd[i].onclick = function () {
                var value = ++bCountInput[this.countNum].value;//数量加一
                bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, value) + "¥";//计算小计
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"
            }
        }
        //对文本框的操作
        for (var i = 0; i < bEle.length; i++) {
            bCountInput[i].countNum = i;
            bCountInput[i].onkeydown = function (e) {
                if ((e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == 8||(e.keyCode >= 96 && e.keyCode <= 105)) {//keyCode是键码值,8是backsp,48=0,57=9,是横着的那排数字
                } else {
                    return false//nan
                }
            };
            bCountInput[i].onblur = function () {
                if (this.value == "") {
                    this.value = 1;//空值强改1并刷新小计
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";
                }
            };
            bCountInput[i].onkeyup = function () {
                if (this.value == "") {//this指向调用它的对象就是文本框拉
                    bTotal[this.countNum].innerHTML = "0¥";//空白
                } else if (this.value == 0) {
                    this.value = 1;//如果为0,强行改为1,并刷新小计
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥"
                } else {
                    bTotal[this.countNum].innerHTML = cacTotal(this.countNum, bPrice, this.value) + "¥";//首先文本框只能输入数字和空值,然后检测文本框为0或为空值时改为1且刷新小计
                }
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价格
            }
        }
        //删除元素
        console.log(bEle.length);
        for (var i = 0; i < bEle.length; i++) {
            eleDelete[i].value = i;
            eleDelete[i].onclick = function () {
                bList.removeChild(bEle[this.value]);//删除节点
                for(var k = 0;k<bEle.length;k++){
                    //重新给所有对象的value/countNum索引值
                    eleDelete[k].value = k;//对删除按钮重新上值
                    buttonSub[k].countNum=k;//对数量加重新上编号(索引)
                    bCountInput[k].countNum=k;//文本框
                    buttonAdd[k].countNum=k;
                }
                allPrice.innerHTML = cacAllPrice(bTotal)+"¥"//刷新总价
            }
        }
    }

    //计算小计
    function cacTotal(index, priceObj, value) {//形参
        return parseFloat(priceObj[index].innerHTML) * parseInt(value);//括号里是单价*数量,parseFloat()返回从位置0开始查看每一个字符,直到找到第一个非有效字符,然后把之前的字符串转换为数字
    }
    //计算总价
    function cacAllPrice(bTotal) {
        var totalPrice=0;//随便定义一个变量为0
        for(var i=0;i<bTotal.length;i++){//遍历所有的小计
            totalPrice += parseFloat(bTotal[i].innerHTML)//加
        }
        return totalPrice;//返回总价格
    }


</script>
</html>

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值