纯原生js实现京东购物车效果

作为一名前端开发人员,购物的逻辑是经常遇到的, 尤其是商城类网站,订餐程序等,都需要购物车, 实际开发中购物车的逻辑相对简单,每一步操作都有后台数据作为支撑, 前端的主要的工作就是请求接口,渲染数据, 进行基础的逻辑判断处理; 但是在没有后台配合的情况下,纯粹的前端实现京东购物的完整逻辑,那就是有一定困难了 。。。
如果是一个前端小白,初学js的时候,一个头两个大, 在遇到购物车这样复杂的逻辑。头发都要掉光光了。。。 话不多说,直接给大家上代码

页面布局

参考京东购物车实现页面布局 页面布局没有深究, 有那么一回事就行

    <div class="container">
        <div class="header">
            <div class="select">
                <input type="checkbox" class="selectall" > 全选
            </div>
            <span>商品</span>
            <span></span>
            <span>单价</span>
            <span>数量</span>
            <span>小计</span>
            <span>操作</span>
        </div>
        <!-- 店铺 -->
        <div class="wrapper">
            <div class="shop-wrap">              
                    <input type="checkbox" class="shopname">
                    <strong>魅嫂青音专卖店</strong>               
            </div>
            <div class="product">
                <ul>
                    <li class="list">
                        <input type="checkbox" class="selectlist">
                        <img src="./cart/s1.jpg" alt="">
                        <p class="title">结婚礼物团扇结婚 结婚用品 女方手捧花结婚结婚扇子中式团扇秀禾服新娘结</p>
                        <p class="kind">红色双圈-双飞燕(成品单扇子)</p>
                        <p class="singleprice">¥248.40</p>
                        <div class="number">
                            <button class="reduce">-</button>
                            <input type="text" class="count" value="4">
                            <button class="addnum">+</button>
                        </div>
                        <p class="countprice">¥993.60</p>
                        <p class="control">
                            <span>删除</span>
                            <br>
                            <span>移入关注</span>
                        </p>
                    </li>
                    <li class="list">
                        <input type="checkbox" class="selectlist">
                        <img src="./cart/s1.jpg" alt="">
                        <p class="title">结婚礼物团扇结婚 结婚用品 女方手捧花结婚结婚扇子中式团扇秀禾服新娘结</p>
                        <p class="kind">红色双圈-双飞燕(成品单扇子)</p>
                        <p class="singleprice">¥194.40</p>
                        <div class="number">
                            <button class="reduce disabled">-</button>
                            <input type="text" class="count" value="1">
                            <button class="addnum">+</button>
                        </div>
                        <p class="countprice">¥194.40</p>
                        <p class="control">
                            <span>删除</span>
                            <br>
                            <span>移入关注</span>
                        </p>
                    </li>
                </ul>
            </div>
        </div>
        <div class="wrapper">
            <div class="shop-wrap">             
                    <input type="checkbox" class="shopname">
                    <strong>礼尚往来礼品专营店</strong>               
            </div>
            <div class="product">
                <ul>
                    <li class="list">
                        <input type="checkbox" class="selectlist">
                        <img src="./cart/s2.jpg" alt="">
                        <p class="title">结婚礼物团扇结婚 结婚用品 女方手捧花结婚结婚扇子中式团扇秀禾服新娘结</p>
                        <p class="kind">红色双圈-双飞燕(成品单扇子)</p>
                        <p class="singleprice">¥119.00</p>
                        <div class="number">
                            <button class="reduce disabled">-</button>
                            <input type="text" class="count" value="1">
                            <button class="addnum">+</button>
                        </div>
                        <p class="countprice">¥119.00</p>
                        <p class="control">
                            <span>删除</span>
                            <br>
                            <span>移入关注</span>
                        </p>
                    </li>
                    <li class="list">
                        <input type="checkbox" class="selectlist">
                        <img src="./cart/s2.jpg" alt="">
                        <p class="title">结婚礼物团扇结婚 结婚用品 女方手捧花结婚结婚扇子中式团扇秀禾服新娘结</p>
                        <p class="kind">红色双圈-双飞燕(成品单扇子)</p>
                        <p class="singleprice">¥119.00</p>
                        <div class="number">
                            <button class="reduce">-</button>
                            <input type="text" class="count" value="2">
                            <button class="addnum">+</button>
                        </div>
                        <p class="countprice">¥238.00</p>
                        <p class="control">
                            <span>删除</span>
                            <br>
                            <span>移入关注</span>
                        </p>
                    </li>
                </ul>
            </div>
        </div>
        <div class="wrapper">
            <div class="shop-wrap">              
                    <input type="checkbox" class="shopname">
                    <strong>智慧礼品官方旗舰店</strong>                
            </div>
            <div class="product">
                <ul>
                    <li class="list">
                        <input type="checkbox" class="selectlist">
                        <img src="./cart/s3.jpg" alt="">
                        <p class="title">结婚礼物团扇结婚 结婚用品 女方手捧花结婚结婚扇子中式团扇秀禾服新娘结</p>
                        <p class="kind">红色双圈-双飞燕(成品单扇子)</p>
                        <p class="singleprice">¥188.00</p>
                        <div class="number">
                            <button class="reduce disabled">-</button>
                            <input type="text" class="count" value="1">
                            <button class="addnum">+</button>
                        </div>
                        <p class="countprice">¥188.00</p>
                        <p class="control">
                            <span>删除</span>
                            <br>
                            <span>移入关注</span>
                        </p>
                    </li>                   
                </ul>
            </div>
        </div>
    </div>
    <div class="combine">
        <p>
            已选择 
            <em class="amount-sum">0</em>
            件商品
        </p>
        <p>
            总价
            <span class="pricetotal priceShow">&yen;0.00</span>
        </p>
    </div>

页面css

页面的核心css 代码,

*{
    margin: 0;
    padding: 0;
}
img{
    display: block;
}
ul,li{
    list-style: none;
}
.container{
    width: 990px;      
    font-size:12px;
    color:#434343;
    margin:0 auto;
}
.header{
    display: flex;
    height: 40px;
    padding:5px 0;
    line-height: 40px;
    margin-bottom:10px;  
}
.select{
    width: 133px;
}
.header span:nth-child(2){
    width: 208px;
}
.header span:nth-child(3){
    width: 170px;
    padding:0 10px 0 20px;
}
.header span:nth-child(4){
    width: 170px;
    padding-right: 50px;
    text-align: right;
}
.header span:nth-child(5){
    width: 80px;
    text-align: center;
}
.header span:nth-child(6){
    width: 140px;
    padding-right: 40px;
    text-align: right;
}
.header span:nth-child(7){
    width: 75px;
}
.shop-wrap{
    height: 30px;
    line-height: 30px;
    padding-left: 11px;
    margin-bottom:10px;
    border-bottom:2px solid #aaa;
}
.list{
    display: flex;
    align-items: flex-start;
    margin-bottom:10px;
    height: 108px; 
}

.selectlist{
    margin-right:20px;
}
.list img{
    width: 80px;
    height: 80px;
    margin-right: 10px;
}
.list .title{
    font-size:12px;
    width: 204px;
    height: 40px;
    line-height: 20px;
    overflow: hidden;

}
.kind{
    width: 160px;
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
    font-size:12px;
}
.singleprice{
    text-align: right;
    width: 190px;
    padding-right: 40px;
}
.number{
    width: 84px;
    display: flex;
    justify-content: flex-start;
}
.number button{
    width: 17px;
    height: 22px;
    background-color: #fff;
    border:1px solid #aaa;
}
.count{
    width:46px;
    height: 20px;
    outline: none;
    border:1px solid #aaa;
    text-align: center;
}
.countprice{
    width: 140px;
    padding-right: 40px;
    text-align: right;
    font-weight: 900;
}
.control{
    width: 75px;
    text-align: left;
}

.disabled{
    cursor:no-drop;
}

.combine{
    width: 990px;
    height: 30px;
    line-height: 30px;
    margin: 0 auto;
    display: flex;
    font-size:12px;
    color:#434343;
    justify-content: flex-start;
}
.amount-sum{
    color:#e2231a;
    font-style: normal;
    font-weight: 900;
}
.combine p{
    margin-right: 20px;
}
.pricetotal{
    font-size:16px;
    font-weight: 900;
    color:#e2231a;
}

页面效果

在这里插入图片描述到此 准备工作已经就绪, 剩下的就是js的逻辑处理

js 完整代码

let selectall = document.querySelector('.selectall');
//  查找所有的店铺
let shopname = document.querySelectorAll('.shopname');
// 查找所有的商品列表
let selectlist = document.querySelectorAll('.selectlist');
//  查找所有的操作数量按钮
let addnum = document.querySelectorAll('.addnum');
let reduce = document.querySelectorAll('.reduce');
let count = document.querySelectorAll('.count');
//  获取 单一商品的价钱 小计 
let countprice = document.querySelectorAll('.countprice');
//  获取 每个商品的单价
let singleprice = document.querySelectorAll('.singleprice');
//  获取 总件数  总价钱
let amount_sum = document.querySelector('.amount-sum');
let pricetotal = document.querySelector('.pricetotal')

//  实现全选的效果
selectall.onclick = function () {    
    let status = this.checked;  
    shopname.forEach(function (item, index) {
        item.checked = status;
    }) 
    selectlist.forEach(function (item, index) {
        item.checked = status;
    })
     //  计算总价和总数
     countTotal()
}

//  点击 加号 改变 商品数量
addnum.forEach(function (item, index) {
    item.onclick = function () {     
        let val = +count[index].value;
        val++;    
        count[index].value = val;      
        reduce[index].classList.remove('disabled'); reduce[index].disabled = false;       
        countSinglePrice(index, val);
   
        let shop_all_product = this.parentElement.parentElement.parentElement.children;      
        let shop_parent = this.parentElement.parentElement.parentElement.parentElement.previousElementSibling.children[0]
        selectShopName(shop_all_product,  shop_parent) ;
        selectAllButton();
        countTotal()
    }
})

//  点击 减号 改变 商品数量
reduce.forEach(function (item, index) {
    item.onclick = function () {     
        //  + 实现隐式类型转换
        let val = +count[index].value;      
        if (val == 1) {
            val = 1;
        } else {
            val--;
        }
        if (val <= 1) {
            this.disabled = true;
            this.classList.add('disabled')
        }
      
        count[index].value = val;      
        countSinglePrice(index, val);
                  
        let shop_all_product = this.parentElement.parentElement.parentElement.children;       
        let shop_parent = this.parentElement.parentElement.parentElement.parentElement.previousElementSibling.children[0]
        selectShopName(shop_all_product,  shop_parent) ;
        selectAllButton();       
         countTotal()
    }
})

//  选择店铺  实现选中该店铺所有的商品
shopname.forEach(function (item, index) {
    item.onclick = function () {
        let shop_status = this.checked;       
        let product_list = this.parentElement.nextElementSibling.children[0].children;
        for (let i = 0; i < product_list.length; i++) {
            product_list[i].children[0].checked = shop_status
        }       
        let shop_number = 0;   
        shopname.forEach(function (item_status, index) {
            if (item_status.checked) {
                shop_number += 1;
            }
        })
       
        if (shopname.length == shop_number) {
            selectall.checked = true;
        } else {
            selectall.checked = false;
        }
        countTotal()
    }
})

//  选择商品 实现店铺选中的效果  函数封装 
//  参数 ele: 店铺下的所有的商品   ; shop_parent 店铺名
function selectShopName(ele,  shop_parent) {  
    let list_number = 0;
    for (let i = 0; i < ele.length; i++) {
        if (ele[i].children[0].checked) {
            list_number++;
        }
    }
  
    if (list_number == ele.length) {
        shop_parent.checked = true;
    } else {
        shop_parent.checked = false;
    }
}

//  选择单一商品 实现店铺的选中 和 全选按钮的选中 
selectlist.forEach(function (item, index) {
    item.onclick = function () {     
        let shop_all_product = this.parentElement.parentElement.children;      
        let shop_parent = this.parentElement.parentElement.parentElement.previousElementSibling.children[0];     
        selectShopName(shop_all_product, shop_parent);      
        selectAllButton();                
        countTotal()
    }
})

//  实现单一商品的价钱计算
function countSinglePrice(index, val) {
    let s_price = Number(singleprice[index].innerHTML.substring(1))
    let single_count_price = (s_price * val).toFixed(2);
    countprice[index].innerHTML = `&yen; ${single_count_price}`;
    //  默认选中该商品
    selectlist[index].checked = true;
}

//  选中所有单一商品 实现全选按钮选中
function selectAllButton(){  
    let single_product = 0; 
    selectlist.forEach(function (single_status, index) {
        if (single_status.checked) {
            single_product++
        }
    })
    if (single_product == selectlist.length) {
        selectall.checked = true;
    } else {
        selectall.checked = false;
    }
}
// 实现商品总价钱和 总数量的计算
function countTotal(){
    let countTotalNumber = 0; // 选中的商品的总数量
    let countTotalPrice = 0; // 选中是商品的总价钱
    count.forEach(function(item, index){
        if(selectlist[index].checked){
            //  计算商品数量
            let num = +item.value;
            countTotalNumber += num;
            //  计算总价钱
            let single_price = Number(countprice[index].innerHTML.substring(1));
            countTotalPrice += single_price ;
        } 
    })
    amount_sum.innerHTML = countTotalNumber;
    pricetotal.innerHTML = `&yen;${countTotalPrice}`;
}


代码很糙,逻辑简单实现; 如果代码存在有问题,欢迎大家指正!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐