JS用面向对象的思想实现的购物车

JS用面向对象的思想实现的购物车

首先先了解面向对象的编写思想。
有面向过程的编程和面向对象的编程。

面向过程:举一个经典例子:把大象放进冰箱里。

首先第一个过程是先打开冰箱,2.然后就是把大象放进去。3.再最后一个过程就是把冰箱关上。这就是面向过程编程的思想。
面向对象的思想:首先先想这些有哪些对象:1.有冰箱、大象。
然后对于冰箱这个对象它有哪些功能呢:1.打开冰箱门。3.把大象放入。2.关闭冰箱门。
了解了这2个思想后,怎么用面向对象的思想实现购物车呢?
首先:搞清楚购物车有哪些对象,只有商品这一个对象。它有哪些属性,有哪些功能。
看效果图
在这里插入图片描述
增加、删除、减少、全选、取消全选功能都有

html部分
在这里插入图片描述
然后JS部分

var goods = [
        {
            id: 1,
            name: "Apple iPhone 12 Pro Max (A2412) 128GB 海蓝色 支持移动联通电信5G 双卡双待手机",
            img_url: "http://img12.360buyimg.com/n1/s450x450_jfs/t1/122505/19/15070/68848/5f861494Ebe330db5/24bc162f493ec940.jpg",
            price: 9299.00,
            count: 1
        },
        {
            id: 2,
            name: "华为 HUAWEI P40 Pro+ 麒麟990 5G SoC芯片 5000万超感知徕卡五摄 100倍双目变焦 8GB+256GB陶瓷黑全网通5G",
            img_url: "http://img10.360buyimg.com/n1/s450x450_jfs/t1/112286/14/8665/320732/5ed23081E43dffed4/2a542499846ace02.jpg",
            price: 7988.00,
            count: 1
        },
        {
            id: 3,
            name: "华为 HUAWEI Mate 40 Pro麒麟9000 5G SoC芯片 超感知徕卡电影影像 66W有线超级快充8GB+256GB亮黑色5G全网通套餐二",
            img_url: "http://img13.360buyimg.com/n1/s450x450_jfs/t1/136340/2/13085/73504/5f917f5cE8f24c5d6/87140d08acee9bf5.jpg",
            price: 6999.00,
            count: 1
        },
        {
            id: 4,
            name: "小米11 Ultra 至尊 5G 骁龙888 2K AMOLED四曲面柔性屏 陶瓷工艺 12GB+256GB 黑色 游戏手机",
            img_url: "http://img13.360buyimg.com/cms/jfs/t1/174632/21/1005/122003/6061b875E54afeca8/e32b75af9e4da505.jpg",
            price: 6499.00,
            count: 1
        },
        {
            id: 5,
            name: "索尼(SONY)Xperia1 II 5G智能手机 4K屏 骁龙865 12G+256G 微单技术 蔡司镀膜 拍照游戏 20帧/秒 夜砚黑",
            img_url: "http://img14.360buyimg.com/n1/s450x450_jfs/t1/151857/40/2398/38943/5f8842b9Edac7df98/0a8a77bfea24aa1d.jpg",
            price: 7499.00,
            count: 1
        }
    ]
    class Car {
        constructor(goods, ul) {
            this.goods = goods;
            this.check_goods = [];
            this.element = document.getElementById(ul);
            this.init();//调用初始化函数。
            this.addEvent()
        }
        //初始化函数
        init() {
            let str = "";
            for (let i = 0; i < this.goods.length; i++) {
                str += `<li index="${this.goods[i].id}">
                        <div class="check">√</div>
                        <img src="${this.goods[i].img_url}"alt="">
                        <p class="good_id">商品编号:${this.goods[i].id}</p>
                        <p class="good_name">${this.goods[i].name}</p>
                        <span class="price">价格:¥${this.goods[i].price}</span>
                        <div class="add_del">
                            <span>数量:</span>
                            <button class="reduce">-</button>
                            <span class="count">${this.goods[i].count}</span>
                            <button class="add">+</button>
                        </div>
                        <button class="del">移除</button>
                    </li>`
            }
            this.element.innerHTML += str;
        };
        //更新用于保存数据的this.goods
        goods_updata(index, num) {//接收2个参数,第一个是商品id,第二个是count某一个商品数量(第二个可以不用传。)
            for (let i = 0; i < this.goods.length; i++) {
                if (this.goods[i].id == index) {//循环找到要改变的商品,然后进行改变其中的数据。
                    if (num) {
                        this.goods[i].count = num;
                    }
                    else {
                        index = Number(index) - 1
                        this.goods.splice(index, 1)
                    }
                }
            }
        };
        //事件委托,给最外面的ul添加点击事件
        addEvent() {
            let ul = document.getElementById("ul");
            let that = this;
            ul.onclick = function (ev) {//当点击ul中的某一个标签的时候,同时传递一个参数ev。
                let e = ev || window.event;
                let tar = e.target//e中有一个target属性,这时候的tar就是ul下你点击的标签。
                switch (tar.className) {//根据tar的点击的标签类名和下面的case进行匹配,然后触发对应的函数。
                    case "reduce":
                        that.reduce(that, tar)//同时把参数传过去。
                        break;
                    case "add":
                        that.add(that, tar)
                        break;
                    case "del":
                        that.del(that, tar)
                        break;
                    case "check":
                        that.check(that, tar);
                        break;
                    case "checked":
                        that.checked(that, tar)
                        break;
                    case "all":
                        that.all(tar)
                        break;
                    case "notall":
                        that.notall(tar)
                }
            }
        };
        //减少商品数量的函数
        reduce(that, tar) {
            let id = Number(tar.parentNode.parentNode.getAttribute("index"))//每一个商品就是一个li标签,同时设置了有个index属性,index就是商品的id。
            let count = tar.nextElementSibling;//获取到减少按钮的下一个兄弟节点(显示商品数量的标签)
            if (count.innerHTML == 1) {//判断数量是否等于1。
                count.innerHTML = 1//等于1就然他就等于1,不能再减少了
            }
            else {//否则就把商品数量进行减一
                count.innerHTML = Number(count.innerHTML) - 1
            }
            that.goods_updata(id, Number(count.innerHTML));//调用之前数据更新的那个函数,同时把id(就是index)和修改后的count值传给该函数。
            this.sum_price()//调用商品价格求和函数,求选中商品的价格。
        };

        //添加商品数量的函数
        add(that, tar) {
            let id = Number(tar.parentNode.parentNode.getAttribute("index"))//同时先获取到你点击的li标签的index属性,商品的id。
            let count = tar.previousElementSibling;//获取到增加按钮的上一个兄弟节点。也就是显示数量的标签。
            count.innerHTML = Number(count.innerHTML) + 1;//增加数量就不需要判断,就直接增加数量。
            that.goods_updata(id, Number(count.innerHTML))//调用数据更新函数。
            this.sum_price()//求选中商品的价格
        }

        //移除商品
        del(that, tar) {
            let id = Number(tar.parentNode.getAttribute("index"))//一样先来获取点击的商品的id
            tar.parentNode.remove();//这里就是移除li标签,就是把商品移除。
            that.goods_updata(id);//然后更新数据,把id传过去。
            this.checked(this, tar)//这里:如果商品选中了,再点击移除按钮的话,就先调用取消选中函数(checked),这样才能保住总价格的动态显示
            this.sum_price()//求和选中商品
        }

        //选中商品给圆圈添加样式,然后用一个数组来存选中后的商品。
        check(that, tar) {
            let li = tar.parentNode;
            li.setAttribute("class", "liactive")//改变标签的类名(class),因为前面的是通过类名class来判断执行哪个函数的。
            tar.setAttribute("class", "checked");
            let check_id = Number(tar.parentNode.getAttribute("index"));//获取商品id
            for (let i = 0; i < that.goods.length; i++) {
                if (that.goods[i].id == check_id) {//通过id判断商品
                    that.check_goods.push(that.goods[i]);//用一个空数组把选中的商品保存进空数组。(因为求商品的函数求和就直接读取该数组就行了)
                }
            }
            this.sum_price()
        }
        //当在点击的话就取消红色样式,取消选中。
        checked(that, tar) {
            //判断是否为全部选中,如果全部选中,就把全部选中按钮进行更改。
            if (this.check_goods.length == this.goods.length) {
                let all = document.getElementById("all")
                all.innerHTML = "选中全部"
                all.setAttribute("class", "all");
            }
            let li = tar.parentNode;
            li.setAttribute("class", "")
            tar.setAttribute("class", "check")
            let check_id = Number(tar.parentNode.getAttribute("index"));
            for (let i = 0; i < that.check_goods.length; i++) {
                if (that.check_goods[i].id == check_id) {//通过id判断选中商品数组中是不是有id这个商品有就删去
                    that.check_goods.splice(i, 1)//把取消的商品从保存选中商品的数组中删去。
                }
            }
            this.sum_price()
        }
        //选中商品价格求和
        sum_price() {
            let total_price = 0
            for (let i = 0; i < this.check_goods.length; i++) {
                total_price += this.check_goods[i].count * this.check_goods[i].price;
            }
            let total = document.getElementById("total_price");
            total.innerHTML = `总价格:¥${total_price}`
        }

        //选中全部商品的按钮。
        all(tar) {
            tar.innerHTML = "取消全部"
            tar.setAttribute("class", "notall")
            let li = document.querySelectorAll("li");
            let check = document.querySelectorAll(".check")
            for (let i = 0; i < li.length; i++) {
                li[i].setAttribute("class", "liactive")
            }
            for (let i = 0; i < check.length; i++) {
                check[i].setAttribute("class", "checked")
            }
            //把现在最新的商品的数据赋值给保存选中商品的数组中
            this.check_goods = [...this.goods]
            this.sum_price()
        }
        //取消全部选中
        notall(tar) {
            tar.innerHTML = "选中全部";
            tar.setAttribute("class", "all");
            let li = document.querySelectorAll("li");
            let check = document.querySelectorAll(".checked")
            for (let i = 0; i < li.length; i++) {
                li[i].setAttribute("class", "")
            }
            for (let i = 0; i < check.length; i++) {
                if (check[i].getAttribute("class") == check) {
                    tar.innerHTML = "选中全部"
                }
                check[i].setAttribute("class", "check")
            }
            this.check_goods = [];
            this.sum_price()
        }

    }
    //调用类Car,同时传参数(商品数量,最外层的ul类名)
    let car = new Car(goods, "ul");
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

没有昵称...

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

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

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

打赏作者

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

抵扣说明:

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

余额充值