原生js方法购物车完整实现 利用localStorage

利用localStorage实现

html页面3个分别是
productList 产品列表 details产品详情页 cartList购物车页面

1.productList.html 页面
 <style>
        body,ul ,li{
            padding: 0;
            margin: 0;
        }
        li{
            list-style: none;
        }
        #productDatas li{
            float: left;
            width: 220px;
            padding: 10px;
            margin: 10px;
            border: 1px solid #000;
        }
        .btn{
            border: none;
            width: 120px;
            height: 30px;
            background: red;
            color: #fff;
        }
    </style>
</head>
<body>
    <ul id="productDatas">
      <!--   <li>//模板写出  注释掉 
            <img src="../img/1.jpg" alt="">
            <p>标题</p>
            <p>价格</p>
            <input type="button" value="加入购物车" class="btn"> 
        </li>
        <li>
            <img src="../img/1.jpg" alt="">
            <p>标题</p>
            <p>价格</p>
            <input type="button" value="加入购物车" class="btn"> 
        </li>
        <li>
            <img src="../img/1.jpg" alt="">
            <p>标题</p>
            <p>价格</p>
            <input type="button" value="加入购物车" class="btn"> 
        </li> -->
    </ul>
</body>
        <script src="../js/cart.js"></script>
    <script>
      /*   let productDatas={//先把商品基本信息列出来,然后利用localStorage存到本地 就可以注释掉
            "10001":{
                id:10001,
                imgsrc:"../img/1.jpg",
                title:"商品1",
                price:100    
            },
            "10002":{
                id:10002,
                imgsrc:"../img/2.jpg",
                title:"商品2",
                price:200    
            },
            "10003":{
                id:10003,
                imgsrc:"../img/3.jpg",
                title:"商品3",
                price:300    
            }
        }
        localStorage.setItem("productDatas",JSON.stringify(productDatas));
         */
			//取到本地商品信息,实际开发是从服务器取数据
        let productDatas=JSON.parse(localStorage.getItem("productDatas"));

        let oProduct=document.getElementById("productDatas");
        let str="";
         for(let id in productDatas){//利用模板字符串把商品信息显示出来
            str+=`  
            <li>
           <a href="details.html?id=${id}">  <img src="${productDatas[id].imgsrc}" alt=""></a>
            <p>${productDatas[id].title}</p>
            <p>${productDatas[id].price}</p>
            <input type="button" value="加入购物车" class="btn" data-id="${id}"> 
            </li>
            `;
         }
         oProduct.innerHTML=str;

         let cart=new Cart();  //调用购物车类
         let oInput=document.querySelectorAll("input");
         for(let i=0;i<oInput.length;i++){
             oInput[i].onclick=function(){
                 let preID=oInput[i].getAttribute("data-id");
                 cart.saveData(preID,1,false);
             }
         }
    </script>
2.details产品详情页 
<body>
    <div class="datails"></div>
</body> 
<script src="../js/cart.js"></script>
<script>
    let oDatails=document.querySelectorAll(".datails")[0];

    let prodID=location.search.split("=")[1];//利用location.search.split取到地址后面跟的数据等号右边的就是id
    // console.log(prodID);
    let productData=JSON.parse(localStorage.getItem("productDatas"))[prodID];//利用id来找到对应的商品的基本信息
    // console.log(productData);
    oDatails.innerHTML=`//然后放到页面中展示
        <img src="${productData.imgsrc}">
        <p>${productData.title}</p>
        <p>${productData.price}</p>
        <span>-</span><input type="text" value="1"><span>+</span>
        <input type="button" value="加入购物车" id="btn">
    `;

    let aSpan=document.querySelectorAll("span");
    let aInput=document.querySelectorAll("input");
    
    aSpan[0].onclick=function(){//给页面中减号添加点击效果
            aInput[0].value--;
            if(aInput[0].value==0){//控制临界值
                aInput[0].value=1;
            }
    }
    aSpan[1].onclick=function(){//加号点击效果
          //一般会有限购和库存限制
        aInput[0].value++;
        
    }
    aInput[0].onchange=function(){//文本框数量显示
        if(aInput[0].value<=1){
            aInput[0].value=1;
        }
    }
    let cart=new Cart();
    aInput[1].onclick=function(){//在给加入购物车按钮添加效果 
        let num=aInput[0].value;
        cart.saveData(prodID,+num,false);//把文本框里数量存到本地
        location.href="cartList.html";//跳转到购物车列表页面
    }

</script>
3.cartList购物车页面
<style>
        li{
            list-style: none;

        }
        img{
            width: 30px;
        }
        .del{
            background: red;
            color: #Fff;
        }
    </style>
</head>
<body>
    <input type="checkbox"  id="checkbox">全选//全选框
    <br>
    <ul id="cartList">//显示商品
    		
    </ul>
    <div id="totalPrice">//显示所有商品的总价
        0
    </div>
</body>
    <script src="../js/cart.js"></script>
    <script>
        let cart=new Cart();
        cart.showList();
    </script>
4.cart.js 创建购物车类  面向对象 上面每个页面都引入此js

class Cart {
    constructor() {
        //判断cartData里是否有数据
        if (localStorage.getItem("cartData")) {//如果有 取出来用
            this.cartData = JSON.parse(localStorage.getItem("cartData"));
        } else {//如果没有 cartData定义一个空对象
            this.cartData = {};
        }
    }

        //num形参变量  
    saveData(perID, num, flag) {//判断caraData有没有这个id的值  //flag为true时,num为终值,为false时,num为累加值
        if (!this.cartData[perID] || flag) {//如果没有给这个id赋值num
            this.cartData[perID] = num;
        } else {//有num累加
            this.cartData[perID] += num;
        }
        localStorage.setItem("cartData", JSON.stringify(this.cartData));//把cartData数据存到本地

    }

    showList() {//购物车页面展示
        this.oCheck = document.getElementById("checkbox");
        this.cartList = document.getElementById("cartList");
        this.totalPrice = document.getElementById("totalPrice");//获取DOM对象
        let productDatas = JSON.parse(localStorage.getItem("productDatas"));//获取本地商品数据
        let str = "";
        for (let id in this.cartData) {//遍历cartData数据里的id,来匹配添加的商品  再把商品展示出来
            str += `
                    <li data-id="${id}">
                    <input type="checkbox" class="ck">    
                    <img src="${productDatas[id].imgsrc}">
                    <span>${productDatas[id].title}</span>
                    <span class="perPrice">${productDatas[id].price}</span>
                    <span class="minus">-</span>
                    <input type="text" value="${this.cartData[id]}" class="num">
                    <span class="plus">+</span>
                    <span class="total">${productDatas[id].price*this.cartData[id]}</span>
                    <span class="del">删除</span>
                    </li>
                
                
                `;
        }
        cartList.innerHTML = str;
            //给需要操作的DOM对象添加类名,在获取它们
        this.ck = document.querySelectorAll(".ck");
        this.perPrice = document.querySelectorAll(".perPrice");
        this.minus = document.querySelectorAll(".minus");
        this.num = document.querySelectorAll(".num");
        this.plus = document.querySelectorAll(".plus");
        this.total = document.querySelectorAll(".total");
        this.del = document.querySelectorAll(".del");
        this.list = document.querySelectorAll("li");  
        //全选
        this.oCheck.onclick = () => {  //列表里的每一个复选框的状态要和全选复选框状态保持一致
            for (let i = 0; i < this.ck.length; i++) {
                 //遍历是取到所有列表的复选框,checked是选中状态
                this.ck[i].checked = this.oCheck.checked;
            }
            this.totalPrices();
        }

        for (let i = 0; i < this.ck.length; i++) {
            this.ck[i].onclick = () => { //判断单个复选框被勾选的数量和复选框的总量是否一致
                let count = 0;//表示勾选的数量默认为0
                for (let j = 0; j < this.ck.length; j++) {
                    if (this.ck[j].checked) { //勾选count+1
                        count++;
                    }
                }
                 //循环结束之后,能算出有多少个勾选的,如果这个勾选的数量和所有复选框的数量相同
                if (count == this.ck.length) { //当count等于this.ck的长度时,全选框勾选
                    this.oCheck.checked = true;
                } else {
                    this.oCheck.checked = false;
                }
                this.totalPrices();
            }
        }
        //减号
        for (let i = 0; i < this.minus.length; i++) {//遍历减号,因为加号和文本框和删除按钮跟它数量一致,所以只用一次循环

            this.minus[i].onclick = () => {//给每个减号添加点击事件
                this.num[i].value--;  //文本框里的值减一
                if (this.num[i].value == 0) { //控制数量的临界值
                    this.num[i].value = 1;
                }
                this.upData(i);//调用upData方法
                this.totalPrices();//改变商品总价的方法
            }
            //加号
            this.plus[i].onclick = () => {//给每个加号添加点击事件
                this.num[i].value++; //文本框值加一
                this.upData(i);
                this.totalPrices();
            }
            //文本框
            this.num[i].onchange=()=>{
                if(this.num[i].value<=1){
                    this.num[i].value=1;
                }
                this.upData(i);
                this.totalPrices();
            }
            //删除
            this.del[i].onclick=()=>{
                let prodID=this.list[i].getAttribute("data-id");
                this.delData(prodID,i);
            }
        }

    }
    upData(i) {
        //单种商品的总价改变
        this.total[i].innerText = this.perPrice[i].innerText * this.num[i].value;
         //购物车数据的改变并保存
        let perID = this.list[i].getAttribute("data-id");

        this.saveData(perID, +this.num[i].value, true);
    }
    totalPrices() {//改变总价
        let totalPrice = 0;
        for (let j = 0; j < this.ck.length; j++) {
            //找到所有勾选的商品单个总价,进行累加
            if (this.ck[j].checked) {
                totalPrice += +this.total[j].innerText;
            }

        }
        this.totalPrice.innerText = totalPrice;
    }
    //删除
    delData(prodID,i){
        //根据id删除对应项
        delete this.cartData[prodID];
        //在存到本地  正常操作是存到服务器
        localStorage.setItem("cartData",JSON.stringify(this.cartData));
        //删除DOM节点
        this.cartList.removeChild(this.list[i]);
        this.ck[i].checked=false;//因为删除DOM结构,页面上的结构消失,但是变量(this.list/this.ck等)里存的值并没有减少,
        //状态没有改变,如果这里也要改变总价,为了保证删除掉的商品不要再被计算在内,需要报对应的复选框的状态置为false

        this.totalPrices();//然后调用计算总价的方法


    }

}
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值