购物车结算功能模块

这个案例拖延了三天,今天终于给补上了。

购物车结算的功能,主要就是更新商品的数据了。主要利用的知识是jQuery中元素的获取、获取元素的子元素或父元素、操作元素属性和元素的文本内容以及对jQuery选择器的应用,等等吧。反正就是把JavaScript里的操作在这里更好的用jQuery实现。

这个案例的核心价值我认为就是数据的获取与转换,以及遍历元素。练习的价值还是挺高的,还有就是更让我们清除的认识到结构的作用。

废话不多说,先看下我们需要实现的几个功能吧。

如图所示,五个部分。

 

1.  全选按钮 和 商品对应的按钮。

这个部分有两个部分,首先是全选按钮选中时下面所有的商品按钮会选中;其次就是商品部分的按钮全选中时全选按钮被选中,有一个商品按钮没有选中时全选按钮就不选中。

这里注册事件是用change事件,表示表单发生变化,简单来说就是表单checked属性发生变化。代码里面的注释很详细了,可以看看哈。

        // 1.实现全选按钮控制小按钮
        // 1.1 小按钮的状态与全选按钮的状态保持一致 prop()固有属性检测表单是否被选中
        $(".checkall").change(function () {
            $(".j-checkbox, .checkall").prop("checked", $(this).prop("checked"));
            // 改变背景色
            if ($(this).prop("checked")) {
                // 添加类 改变背景色
                $(this).parents(".cart-item").addClass("check-cart-item");
            } else {
                // 移除类
                $(this).parents(".cart-item").toggleClass("check-cart-item");
            }
            getSum();
        })

        // 1.2 小按钮的状态决定全选按钮状态
        $(".j-checkbox").change(function () {
            // if(按钮选中的个数 === 按钮的总个数){
            // 全选选中
            // }else{
            // 不选择全选
            // }
            if ($(".j-checkbox:checked").length === $(".j-checkbox").length) {
                $(".checkall").prop("checked", true);
            } else {
                $(".checkall").prop("checked", false);
            }
            // 选中时,背景色改变
            // ele.parents("指定父级元素")
            if ($(this).prop("checked")) {
                $(this).parents(".cart-item").addClass("check-cart-item");
            } else {
                $(this).parents(".cart-item").toggleClass("check-cart-item");
            }
            // 重新计算小计部分
            getSum();
        })

 

2. 点击+ - 按钮,实现商品数量的变化;3. 按钮-/+改变商品数量,同时更新商品总价

这里就是注册点击事件,核心就是确定的是当前点击的按钮对应的表单的值变化。通过当前点击的元素找到对应的表单,获取表单的值是使用val()方法,普通元素的内容是text()和html()。+按钮的实现过程与-相似,+有详细的过程。-按钮需要做一个判断,商品数不能小于0.

这里我们这更新总价放一块了,以为点击-/+按钮时,右边的小计部分就要实时变化。

        // 2.点击+ -按钮来增加和减少商品数量
        // 2.1 +添加数量
        $(".increment").click(function () {
            // 获取当前 + 的兄弟表单的值 
            var n = $(this).siblings(".itxt").val();
            // 然后点击一次自增——商品数量
            n++;
            // console.log(n);
            // 数量:表单的商品数量
            $(this).siblings(".itxt").val(n);
            // 当前被点击的 + 区域对应的单价
            var p = $(this).parents(".p-num").siblings(".p-price").text();
            // 返回的是字符串 所以要把¥截取掉 使用substr()截取
            // 截取后还是字符串,用parseFloat转换为数值型
            p = parseFloat(p.substr(1));
            console.log(p);
            // 获取当前的总价
            var price = $(this).parents(".p-num").siblings(".p-sum").text();
            // 去掉¥符号
            price = parseFloat(price.substr(1));
            // 保留两位小数点 toFixed(2)
            price = (p * n).toFixed(2);
            console.log(price);
            // 把计算好的商品总和价放到标签里
            $(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
            // 重新计算小结部分的总额
            getSum();
        })
        // 2.2 -号减少数量 
        $(".decrement").click(function () {
            // 一定是当前加号的兄弟表单的值自增
            var n = $(this).siblings(".itxt").val();
            // 商品数量
            n--;
            console.log(n);
            // 三元表达式:判断数量不能小于0
            n = n <= 0 ? 1 : n;
            $(this).siblings(".itxt").val(n);
            // 当前+号区域的单价
            var p = $(this).parents(".p-num").siblings(".p-price").text();
            p = parseFloat(p.substr(1));
            console.log(p);
            // 获取当前的总价
            var price = $(this).parents(".p-num").siblings(".p-sum").text();
            // 去掉¥符号
            price = parseFloat(price.substr(1));
            price = (p * n).toFixed(2);
            console.log(price);
            $(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
            getSum();
        })

做到这里,能实现点击-/+按钮,改变商品数量,对应的小计也发生变化。但是,这里存在一个bug,就是当用户自己输入商品数量时,小计部分的总额是不变化的,这就很惊悚了。

所以,这里还需要判断一下用户改变表单内容的事件。可以用change事件注册,但是用户体验不好,需要在空白处点击一次小计才会更新,这里我用的是键盘弹起keyup事件。

    // 3. 这样的话 有一个bug,当用户自己更改表单的内容时就会出错
        $(".itxt").keyup(function () {
            var n = $(this).val();
            var p = $(this).parents(".p-num").siblings(".p-price").text();
            p = parseFloat(p.substr(1));
            var price = $(this).parents(".p-num").siblings(".p-sum").text();
            // 去掉¥符号
            price = parseFloat(price.substr(1));
            price = (p * n).toFixed(2);
            console.log(price);
            $(this).parents(".p-num").siblings(".p-sum").text("¥" + price);
            getSum();
        })

 

4. 结算购物车部分

这部分用到了jQuery元素的遍历,each()。jQuery中存在的隐式迭代是对不同元素进行相同的操作,现在我们需要对不同的元素做不同的操作,此时我们就需要遍历元素了。遍历每个模块中的商品数量进行累加就是购物车总数量,遍历每个模块中的商品小计进行累加就是购物车结算总额。我们可以封装一个函数,因为只有有变动我们都需要更新数据,实时更新购物车对应的数据,所以封装一个函数比较好。这就不难解释,为什么每次点击-/+按钮时,需要在最后调用一次本函数了。

注意:只有商品被选中时,才会参与购物车结算的。

    // 封装一个函数,用来计算小结的内容
        function getSum() {
            var totalNumber = 0; // 总件数
            var totalPrice = 0; // 总价钱
            // 遍历car-item所有的表单中的商品数量 累加 算出所有商品的总数量
            $(".itxt").each(function (i, ele) {
                // 判断 商品对应的按钮是否选中,选中才会结算 不选中不参与结算
                var singleBtn = $(this).parents(".p-num").siblings(".p-checkbox").children(".j-checkbox");
                if (singleBtn.prop("checked")) {
                    totalNumber += parseFloat($(ele).val());
                }
            })
            $(".amount-sum em").text(totalNumber);

            // 遍历每个car-item中的商品总计 累加起来算出所有商品价
            $(".p-sum").each(function (i, ele) {
                var singleBtn = $(this).siblings(".p-checkbox").children(".j-checkbox");
                if (singleBtn.prop("checked")) {
                    totalPrice += parseFloat($(ele).text().substr(1));
                }
            })
            $(".price-sum em").text("¥" + totalPrice.toFixed(2));
        }

 

5.删除模块

这部分比较简单,就是点击事件的注册,主要是要找到点击时,删除对应的父结构。切记切记,删除的永远是当前被点击按钮对应的结构,核心就是this的问题。

        // 5. 删除模块
        // 删除按钮
        $(".p-action a").click(function () {
            $(this).parents(".cart-item").remove();
            getSum();
        })
        // 删除选中的商品
        $(".operation .remove-batch").click(function () {
            $(".j-checkbox:checked").parents(".cart-item").remove();
            getSum();
        })
        // 清空购物车
        $(".operation .clear-all").click(function () {
            $(".cart-item").remove();
            getSum();
        })

删除第一个后:

点击删除所选中商品按钮:

清空:

 

最后附上结构代码,一个商品列部分。

                    <div class="cart-item">
                        <div class="p-checkbox">
                            <input type="checkbox" name="" id="" class="j-checkbox">
                        </div>
                        <div class="p-goods">
                            <div class="p-img">
                                <img src="upload/p2.jpg" alt="">
                            </div>
                            <div class="p-msg">【2000张贴纸】贴纸书 3-6岁 贴画儿童 贴画书全套12册 贴画 贴纸儿童 汽</div>
                        </div>
                        <div class="p-price">¥24.80</div>
                        <div class="p-num">
                            <div class="quantity-form">
                                <a href="javascript:;" class="decrement">-</a>
                                <input type="text" class="itxt" value="1">
                                <a href="javascript:;" class="increment">+</a>
                            </div>
                        </div>
                        <div class="p-sum">¥24.80</div>
                        <div class="p-action"><a href="javascript:;">删除</a></div>
                    </div>

 

完整的html 

<div class="c-container">
        <div class="w">
            <div class="cart-filter-bar">
                <em>全部商品</em>
            </div>
            <!-- 购物车主要核心区域 -->
            <div class="cart-warp">
                <!-- 头部全选模块 -->
                <div class="cart-thead">
                    <div class="t-checkbox">
                        <input type="checkbox" name="" id="" class="checkall"> 全选
                    </div>
                    <div class="t-goods">商品</div>
                    <div class="t-price">单价</div>
                    <div class="t-num">数量</div>
                    <div class="t-sum">小计</div>
                    <div class="t-action">操作</div>
                </div>
                <!-- 商品详细模块 -->
                <div class="cart-item-list">
                    <div class="cart-item check-cart-item">
                        <div class="p-checkbox">
                            <input type="checkbox" name="" id="" checked class="j-checkbox">
                        </div>
                        <div class="p-goods">
                            <div class="p-img">
                                <img src="upload/p1.jpg" alt="">
                            </div>
                            <div class="p-msg">【5本26.8元】经典儿童文学彩图青少版八十天环游地球中学生语文教学大纲</div>
                        </div>
                        <div class="p-price">¥12.60</div>
                        <div class="p-num">
                            <div class="quantity-form">
                                <a href="javascript:;" class="decrement">-</a>
                                <input type="text" class="itxt" value="1">
                                <a href="javascript:;" class="increment">+</a>
                            </div>
                        </div>
                        <div class="p-sum">¥12.60</div>
                        <div class="p-action"><a href="javascript:;">删除</a></div>
                    </div>
                    <div class="cart-item">
                        <div class="p-checkbox">
                            <input type="checkbox" name="" id="" class="j-checkbox">
                        </div>
                        <div class="p-goods">
                            <div class="p-img">
                                <img src="upload/p2.jpg" alt="">
                            </div>
                            <div class="p-msg">【2000张贴纸】贴纸书 3-6岁 贴画儿童 贴画书全套12册 贴画 贴纸儿童 汽</div>
                        </div>
                        <div class="p-price">¥24.80</div>
                        <div class="p-num">
                            <div class="quantity-form">
                                <a href="javascript:;" class="decrement">-</a>
                                <input type="text" class="itxt" value="1">
                                <a href="javascript:;" class="increment">+</a>
                            </div>
                        </div>
                        <div class="p-sum">¥24.80</div>
                        <div class="p-action"><a href="javascript:;">删除</a></div>
                    </div>
                    
                </div>

                <!-- 结算模块 -->
                <div class="cart-floatbar">
                    <div class="select-all">
                        <input type="checkbox" name="" id="" class="checkall">全选
                    </div>
                    <div class="operation">
                        <a href="javascript:;" class="remove-batch"> 删除选中的商品</a>
                        <a href="javascript:;" class="clear-all">清理购物车</a>
                    </div>
                    <div class="toolbar-right">
                        <div class="amount-sum">已经选<em>1</em>件商品</div>
                        <div class="price-sum">总价: <em>¥12.60</em></div>
                        <div class="btn-area">去结算</div>
                    </div>
                </div>
            </div>
        </div>

    </div>

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章