jQuery实现当当购物车结算、全选、计数等功能

一、效果图

二、HTML布局

<div class="content">
        <div class="logo">
            <img src="images/dd_logo.jpg"><span class="closePage">关闭</span>
        </div>
        <div class="menuList">
            <span><input type="checkbox" name="chooseall">全选</span>
            <span>商品信息</span>
            <span>单价(元)</span>
            <span>数量</span>
            <span>金额(元)</span>
            <span>操作</span>
        </div>
        <hr class="menuBr">
        <div class="ddSelf ">
            <input type="checkbox" name="chooseallself">
            <img src="images/logo1.PNG" alt="">
            <p>当当自营</p>
        </div>
        <div class="cartList">
            <ul>
                <li class="bookImg">
                    <input type="checkbox" name="choose">
                    <img src="images/dog.jpg" alt="" >
                </li>
                <li class="boosName">一起活下来</li>
                <li>¥<input type="text" name="price" value="20.90"></li>
                <li>
                    <input type="button" name="minus" value="-"><input type="text" name="amount" value="1"><input
                        type="button" name="plus" value="+">
                </li>
                <li id="price">¥20.90</li>
                <li>
                    <p>移入收藏</p>
                    <p class="delShopping">删除</p>
                </li>
            </ul>
            <ul>
                <li class="bookImg">
                    <input type="checkbox" name="choose">
                    <img src="images/mai.jpg" alt="">
                </li>
                <li class="boosName">灰霾·来了!</li>
                <li>¥<input type="text" name="price" value="24.00"></li>
                <li>
                    <input type="button" name="minus" value="-"><input type="text" name="amount" value="1"><input
                        type="button" name="plus" value="+">
                </li>
                <li id="price">¥24.00</li>
                <li>
                    <p>移入收藏</p>
                    <p class="delShopping">删除</p>
                </li>
            </ul>
            <ol class="endPrice">
                <li><span>结算</span></li>
            </ol>
        </div>
    </div>

三、效果板块分析

1、全选、反选、部分选择商品
2、页面关闭/打开
3、删除商品(删除完将关闭结算)
4、计数显示商品个数(控制数量最小为“1”)
5、价格随数量的改变而改变
6、指定结算商品(未选择商品结算弹出窗口)
7、结算显示所选信息

四、代码分别实现板块功能

1、全选、反选、部分选择商品

    // 全选选中所有
    $("input[name=chooseall]").on("click", function () {
        //获取全选节点
        const isChoose = $("input[name=chooseall]").prop("checked");
        if (isChoose) {
            //商品全选
            $("input[name=choose]").prop("checked", true);
            //店铺选择
            $("input[name=chooseallself]").prop("checked", true);
        } else {
            $("input[name=choose]").prop("checked", false);
            $("input[name=chooseallself]").prop("checked", false);
        }
    });
  • 选择全选应该将所有的商品及店铺选中
// 店铺全选选中店铺的所有
    $("input[name=chooseallself]").on("click", function () {
        const isChoose = $("input[name=chooseallself]").prop("checked");
        if (isChoose) {
            $("input[name=choose]").prop("checked", true);
        } else {
            $("input[name=choose]").prop("checked", false);
            //不选择总全选框
            $("input[name=chooseall]").prop("checked", false);
        }
    });
  • 店铺全选应选中所有店铺的商品,并且将总的全选框去掉
    部分选择的时候,首先判断商品个数和商品是否选择
   // 创建数组接收CheckBox的值
    let isChecked = new Array(ulLen);
  • 点击当前checkbox进行判断
// 点击CheckBox
    $("input[name=choose").on("click", function () {
        // 建立开关
        let otherChecked = true;
        // 接收当前框的值
        let fla = $(this).prop("checked");
        // 判断当前框是第几个
        let isNumber = $(this).parent().parent().index();//index()判断节点在父节点的位置,从0开始
        // 循环查找非当前勾选框的值
        for (let index = 0; index < ulLen; index++) {
            if (index != isNumber) {
                // 将非当前的勾选框值设置到数组中
                let isO = $(".cartList").find($("input[name=choose")).eq(1).prop("checked");//eq()选择第几个节点
                isChecked.push(isO);
            }
        }
        // 循环勾选框判断数组的值
        for (const index in isChecked) {
            const element = isChecked[index];
            console.log(`数组值${element}`);
            if (element == false) {
            //  循环判断是否有CheckBox没有被选中,如果有一个没有选中那么都是false
                otherChecked = false;
                break;
            }
            // 判断数组的所有值和当前勾选框的值
            //  如果当前选中以及其他商品都是选中状态,那么将选中店铺全选
            if (otherChecked == fla) {
                $("input[name=chooseallself]").prop("checked", true);
            } else {
                //未选中都将取消店铺和所有的全选功能
                $("input[name=chooseallself]").prop("checked", false);
                $("input[name=chooseall]").prop("checked", false);
            }
        }
    });

2、页面关闭/打开
分析:点击关闭之后应该在按钮上显示打开

    // 创建开关,控制关闭信息
    let isShow = false;
  //当点击关闭的时候按钮设置为打开,反之同理
   $(".closePage").click(function () {
        if (isShow == true) {
            $(".closePage").html("关闭");
            isShow = false;
        } else {
            $(".closePage").html("打开");
            isShow = true;
        }
      //jQuery的动画效果
        $(".menuBr ~ div").fadeToggle("slow");
    });

3、删除商品(删除完将关闭结算)

    // 删除
    $(".delShopping").click(function () {
        // 移除本身的父节点所有信息
        $(this).parent().parent().remove();
        // 当移除完所有信息后隐藏结算
        if ($(".cartList ul").length == 0) {
            $(".endPrice").hide();
        }
    });
  • 父节点下的子节点长度为0的时候全部删除了
    4、计数显示商品个数(控制数量最小为“1”)
  • 判断商品个数,有数组接收并将每个商品的初始值设为1
    // 创建数组,个数为商品的个数,并附初值为1
    let timeArr = new Array();
    const ulLen = $(" .cartList ul").length;
    for (let index = 0; index < ulLen; index++) {
      //循环将1赋值给数组
        timeArr.push(1);
    }
  • 点击累加 变化输入框的数量
   // 点击累加 变化输入框的数量...清掉减到为1的样式
   $("input[name=plus]").on("click", function () {
        // 当前节点时该父元素的第几个元素
        const thisNum = $(this).parent().parent().index();
        // 当前个数累加
        timeArr[thisNum] = timeArr[thisNum] + 1;
        //清除个数减到“1”的样式
        $(this).siblings("input[name=amount]").css({ "color": "black", "background": "none" });
        $(this).siblings("input[name=amount]").val(timeArr[thisNum]);
       });
  • 点击累减(减到1的时间将不能再减)
 // 点击累减 变化输入框的数量...减到为1时设置样式
    $("input[name=minus]").on("click", function () {
        // 当前节点时该父元素的第几个元素
        const thisNum = $(this).parent().parent().index();
      // 固定个数只能减到1
        if (timeArr[thisNum] > 1) {
            timeArr[thisNum] = timeArr[thisNum] - 1;
            $(this).siblings("input[name=amount]").val(timeArr[thisNum]);          
            allPrice(this, timeArr[thisNum]);
        }
      //减到1的时候设置样式,变为灰色
        if (timeArr[thisNum] === 1) {
            $(this).siblings("input[name=amount]").css({ "color": "gray", "background": "#eeeeee" });
        }
    });

5、价格随数量的改变而改变

  • 分析:获取当前商品的个数及价格,与商品数量变化相结合运算
  • 封装一个价格方法,使增加数量和减少数量都能调用(可传参(当前商品的位置,商品个数))
 // 封装一个设置价格的方法
    function allPrice(thisSelf, num) {
      //  获取当前商品的价格
        let dPrice = $(thisSelf).parent().parent().children("li").children("input[name=price]").val();
     //  价格*数量
        let onePrice = parseFloat(dPrice * num).toFixed(2);//截取 (获取价格字符串),从第二位开始的后面所有字符
    //设置当前商品的总价格
        $(thisSelf).parent().parent().children("#price").html("¥" + onePrice);
    }
  • 在商品个数的加减中调用方法
allPrice(this, timeArr[thisNum]);

6、指定结算商品(未选择商品结算弹出窗口)

  • 为结算弹出窗口提示
  • 添加结算后的节点,结算所结算的内容
    let aPrice = $("<p></p>")
  • 声明变量接收总价
    let accountPrice = 0;
  • 声明变量接收书名
    let nameAll = ""
  • 声明变量接收书名
    let msgBox = " "
  • 声明变量接收那些商品被选中
    let isCheck = true
  • 循环判断选中的商品结算
for (let index = 0; index < ulLen; index++) {
            // 判断勾选框是否勾选,如果勾选则结算
            isCheck = $(".cartList").find($("input[name=choose")).eq(index).prop("checked");
            if (isCheck) {
                // 循环得到价格信息
                let priceO = $(".cartList ul").eq(index).children("#price").html();
                // 获取选择的书籍名称
                let nameOne = $(".cartList ul").eq(index).children(".boosName").html();
                // 截取价格信息得到浮点的价格
                let intPrice = parseFloat(priceO.substring(1, priceO.length));
                // 得到所选书籍的名字 
                nameAll += "《"+nameOne + "》";

                // 累加价格
                accountPrice += intPrice;
                msgBox = `选择了书籍:${nameAll} 共计:¥${accountPrice}`;
            }

        }
 // 判断是否已经结算,如果已经结算之后就不能再次结算(添加节点)
        let lastp = $(this).next().length;
        // 创建p标签并添加内容
        let aPrice = $("<p></p>").html(msgBox);
        if (lastp == 0) {
            // 判断是否有选择书籍
            if (accountPrice == "") {
                alert(`请选择书籍!`);
            } else {
                $(".cartList").append(aPrice);
            }
        }
        //如果已经结算后,更改商品信息将覆盖掉之前结算的信息
        if (lastp == 1) {
            $(".cartList>p").replaceWith(aPrice);
        }

结算的所有js代码

 // 总价
    $(".endPrice").on("click", function () {
        // 声明变量接收总价
        let accountPrice = 0;
        // 接收书名
        let nameAll = ""
        let isCheck = true;
        // 结算后总提示信息
        let msgBox = " ";
        for (let index = 0; index < ulLen; index++) {
            // 判断勾选框是否勾选,如果勾选则结算
            isCheck = $(".cartList").find($("input[name=choose")).eq(index).prop("checked");
            if (isCheck) {
                // 循环得到价格信息
                let priceO = $(".cartList ul").eq(index).children("#price").html();
                // 获取选择的书籍名称
                let nameOne = $(".cartList ul").eq(index).children(".boosName").html();
                // 截取价格信息得到浮点的价格
                let intPrice = parseFloat(priceO.substring(1, priceO.length));
                // 得到所选书籍的名字 
                nameAll += "《"+nameOne + "》";
                // 累加价格
                accountPrice += intPrice;
                msgBox = `选择了书籍:${nameAll} 共计:¥${accountPrice}`;
            }
        }
        // 判断结算下面是不是有其他标签,如果已经结算之后就不能再次结算
        let lastp = $(this).next().length;
        // 创建p标签并添加内容
        let aPrice = $("<p></p>").html(msgBox);
        if (lastp == 0) {
            // 判断是否有选择书籍
            if (accountPrice == "") {
                alert(`请选择书籍!`);
            } else {
                $(".cartList").append(aPrice);
            }
        }
        if (lastp == 1) {
            $(".cartList>p").replaceWith(aPrice);
        }
    });

注意:一定要引用jQuery的包

最后加上CSS样式

body, ul, li, div, p, h1, h2, ol {
    margin: 0;
    padding: 0;
}

ul, li, ol {
    list-style: none;
}

.content {
    width: 850px;
    margin: 0 auto;
    font-family: "微软雅黑";
}

.logo {
    margin: 10px 0;
}

.logo span {
    display: inline-block;  
    width: 60px;
    height: 30px;
    line-height: 30px;
    font-size: 14px;
    background: #ff0000;
    color: #ffffff;
    text-align: center;
    border-radius: 10px;
    margin-top: 5px;
    margin-right: 10px;
    cursor: pointer;
    font-weight: bold;
    float: right;
}

.menuList {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    color: #666666;
    padding-right: 30px;
}

.menuBr {
    border: rgba(0, 0, 0, 0.1) 1px solid;
    margin-top: 10px;
    margin-bottom: 15px;
}

.ddSelf {
    font-size: 13px;
    color: #000000;
    font-weight: bold;
    display: flex;
    width: 110px;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.ddSelf img {
    width: 30px;
    height: 20px;
    border-radius: 50%;
}

.cartList {
    height: 414px;
    overflow: hidden;
}

.cartList ul {
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: rgba(218, 218, 218, 0.3);
    padding: 20px 25px;
    border: #dddddd 1px solid;
}

.bookImg img {
    max-height: 100px;
}

.bookImg {
    width: 30px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100px;
}

.cartList ul li {
    font-family: "微软雅黑";
    font-size: 12px;
    color: #666666;
    text-align: center;
    line-height: 25px;
    float: left;
}

.cartList ul li input[name="price"] {
    border: none;
    background: transparent;
    width: 45px;
    text-align: center;
}

.cartList ul li input[name="amount"] {
    width: 45px;
    text-align: center;
    border: 1px solid #999999;
    border-left: none;
    border-right: none;
    height: 21px;
}

.cartList ul li input[name="minus"], .cartList ul li input[name="plus"] {
    height: 25px;
    border: 1px #999999 solid;
    width: 25px;
    text-align: center;
}


.cartList ul li p {
    cursor: pointer;
}

.cartList ol {
    float: right;
    clear: both;
    margin-top: 10px;
}
    
.cartList ol li:nth-of-type(1) {
    color: #ff0000;
    width: 120px;
}

.delShopping:hover{
    color: #ff0000;
}

.endPrice li span {
    display: inline-block;
    width: 80px;
    height: 35px;
    line-height: 35px;
    font-size: 14px;
    font-family: "微软雅黑";
    background: #ff0000;
    color: #ffffff;
    text-align: center;
    cursor: pointer;
    font-weight: bold;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容