zoukankan      html  css  js  c++  java
  • 在老王指导下第一次完成购物车!!!

    bom的学习已经接近尾声!终于可以写动态的购物车了!分享一下:

    以下是代码和注解(开始的时候一定要把注解写清楚不然容易把自己绕晕!! 注意this 和 let 的用法!!!)

    <!DOCTYPE html>
    <html>

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>原生JS实现购物车结算功能代码</title>
        <link rel="stylesheet" href="../css/style.css" />
        <style>
            .reduce {
                cursor: no-drop;
            }
            /* @charset "utf-8"; */
    *{margin:0;padding:0;list-style-type:none;}
    a{color:#666;text-decoration:none;}
    table{border-collapse:collapse;border-spacing:0;border:0;}
    body{color:#666;font:12px/180% Arial, Helvetica, sans-serif, "新宋体";}
    clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden}
    .clearfix{display:inline-table}
    *html .clearfix{height:1%}
    .clearfix{display:block}
    *+html .clearfix{min-height:1%}
    .fl{float:left;}
    .fr{float:right;}
    /*素材家园 - www.sucaijiayuan.com*/
    .catbox{940px;margin:100px auto;}
    .catbox table{text-align:center;100%;}
    .catbox table th,.catbox table td{border:1px solid #CADEFF;}
    .catbox table th{background:#e2f2ff;border-top:3px solid #a7cbff;height:30px;}
    .catbox table td{padding:10px;color:#444;}
    .catbox table tbody tr:hover{background:RGB(238,246,255);}
    .checkbox{60px;}
    .check-all{ vertical-align:middle;}
    .goods{300px;}
    .goods span{180px;margin-top:20px;text-align:left;float:left;}
    .goods img{100px;height:80px;margin-right:10px;float:left;}
    .price{130px;}
    .count{90px;}
    .count .add, .count input, .count .reduce{float:left;margin-right:-1px;position:relative;z-index:0;}
    .count .add, .count .reduce{height:23px;17px;border:1px solid #e5e5e5;background:#f0f0f0;text-align:center;line-height:23px;color:#444;}
    .count .add:hover{color:#f50;z-index:3;border-color:#f60;cursor: pointer;}
    .count .reduce:hover{color:#f50;z-index:3;}
    .count input{50px;height:15px;line-height:15px;border:1px solid #aaa;color:#343434;text-align:center;padding:4px 0;background-color:#fff;z-index:2;}
    .subtotal{150px;color:red;font-weight:bold;}
    .operation span:hover,a:hover{cursor:pointer;color:red;text-decoration:underline;}

    .foot{margin-top:0px;color:#666;height:48px;border:1px solid #c8c8c8;border-top:0;background-color:#eaeaea;background-image:linear-gradient(RGB(241,241,241),RGB(226,226,226));position:relative;z-index:8;}
    .foot div, .foot a{line-height:48px;height:48px;}
    .foot .select-all{80px;height:48px;line-height:48px;color:#666;text-align:center;}
    .foot .delete{padding-left:10px;}
    .foot .closing{border-left:1px solid #c8c8c8;103px;text-align:center;color:#666;font-weight:bold;cursor:pointer;background-image:linear-gradient(RGB(241,241,241),RGB(226,226,226));}
    .foot .closing:hover{background-image:linear-gradient(RGB(226,226,226),RGB(241,241,241));color:#333;}
    .foot .total{margin:0 20px;cursor:pointer;}
    .foot  #priceTotal, .foot #selectedTotal{color:red;font-family:"Microsoft Yahei";font-weight:bold;}
    .foot .selected{cursor:pointer;}
    .foot .selected .arrow{position:relative;top:-3px;margin-left:3px;}
    .foot .selected .down{position:relative;top:3px;display:none;}
    .show .selected .down{display:inline;}
    .show .selected .up{display:none;}
    .foot .selected:hover .arrow{color:red;}
    .foot .selected-view{938px;border:1px solid #c8c8c8;position:absolute;height:auto;background:#ffffff;z-index:9;bottom:48px;left:-1px;display:none;}
    .show .selected-view{display:block;}
    .foot .selected-view div{height:auto;}
    .foot .selected-view .arrow{font-size:16px;line-height:100%;color:#c8c8c8;position:absolute;right:330px;bottom:-9px;}
    .foot .selected-view .arrow span{color:#ffffff;position:absolute;left:0px;bottom:1px;}

    #selectedViewList{padding:10px 20px 10px 20px;}
    #selectedViewList div{display:inline-block;position:relative;100px;height:80px;border:1px solid #ccc;margin:10px;float:left;}
    #selectedViewList div img{100px;height:80px;margin-right:10px;float:left;}
    #selectedViewList div span{display:none;color:#ffffff;font-size:12px;position:absolute;top:0px;right:0px;60px;height:18px;line-height:18px;text-align:center;background:#000;cursor:pointer;}
    #selectedViewList div:hover span{display:block;}
        </style>
    </head>

    <body>
        <div class="catbox">
            <table id="cartTable">
                <thead>
                    <tr>
                        <th>
                            <label>
                                <input class="check-all check" type="checkbox" />&nbsp;&nbsp;全选</label>
                        </th>
                        <th>商品</th>
                        <th>单价</th>
                        <th>数量</th>
                        <th>小计</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
                        <td class="goods"><img src="../images/1.jpg" alt="没有图片" /><span>Casio/卡西欧 EX-TR350</span></td>
                        <td class="price">5999.88</td>
                        <td class="count"><span class="reduce"></span>
                            <input class="count-input" type="text" value="1" />
                            <span class="add">+</span></td>
                        <td class="subtotal">5999.88</td>
                        <td class="operation"><span class="delete">删除</span></td>
                    </tr>
                    <tr>
                        <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
                        <td class="goods"><img src="../images/2.jpg" alt="没有图片" /><span>Canon/佳能 PowerShot SX50 HS</span></td>
                        <td class="price">3888.50</td>
                        <td class="count"><span class="reduce"></span>
                            <input class="count-input" type="text" value="1" />
                            <span class="add">+</span></td>
                        <td class="subtotal">3888.50</td>
                        <td class="operation"><span class="delete">删除</span></td>
                    </tr>
                    <tr>
                        <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
                        <td class="goods"><img src="../images/3.jpg" alt="没有图片" /><span>Sony/索尼 DSC-WX300</span></td>
                        <td class="price">1428.50</td>
                        <td class="count"><span class="reduce"></span>
                            <input class="count-input" type="text" value="1" />
                            <span class="add">+</span></td>
                        <td class="subtotal">1428.50</td>
                        <td class="operation"><span class="delete">删除</span></td>
                    </tr>
                    <tr>
                        <td class="checkbox"><input class="check-one check" type="checkbox" /></td>
                        <td class="goods"><img src="../images/4.jpg" alt="没有图片" /><span>Fujifilm/富士 instax mini 25</span></td>
                        <td class="price">640.60</td>
                        <td class="count"><span class="reduce"></span>
                            <input class="count-input" type="text" value="1" />
                            <span class="add">+</span></td>
                        <td class="subtotal">640.60</td>
                        <td class="operation"><span class="delete">删除</span></td>
                    </tr>
                </tbody>
            </table>
            <div class="foot" id="foot">

                <a class="fl" id="deleteAll" href="javascript:;">删除</a>
                <div class="fr closing" onclick="getTotal();">结 算</div>
                <input type="hidden" id="cartTotalPrice" />
                <div class="fr total">合计:¥<span id="priceTotal">0.00</span></div>
                <div class="fr selected" id="selected">已选商品<span id="selectedTotal">0</span>件<span
                        class="arrow up">︽</span><span class="arrow down">︾</span></div>
                <div class="selected-view">
                    <div id="selectedViewList" class="clearfix">
                        <div><img src="../images/1.jpg"><span>取消选择</span></div>
                    </div>
                    <span class="arrow">◆<span>◆</span></span>
                </div>
            </div>
        </div>
    </body>
    <script>

        var checkAll = document.getElementsByClassName("check-all")[0];
        var checkOneList = document.getElementsByClassName("check-one");

        var addList = document.getElementsByClassName("add");
        var reduceList = document.getElementsByClassName("reduce");

        var deleteList = document.getElementsByClassName("delete");
        var deleteAll = document.getElementById("deleteAll");

        var selectedTotal = document.getElementById("selectedTotal");
        var priceTotal = document.getElementById("priceTotal");

        // 删除  两个细节
        // 1.  单删   
        //     每次删除商品之后  判断  如果剩余的商品全部被选中 => 全选框 变为选中状态

        // 2.  商品全部删除之后 (bug  商品全部删除之后  全选框依旧被选中)
        //     原因 (isCheckAll  封装时用的是假设法   商品全部删除之后,checkOneList为0 循环不会执行  flag依旧为true)
        //     解决方法  加一个长度判断   如果checkOneList为0(没有商品)  全选框取消全选

        // 单删  
        for (let i = 0; i < deleteList.length; i++) {
            let del = deleteList[i];
            del.onclick = function () {
                if (confirm("是否删除该商品?")) {
                    var tr = parent(parent(this));
                    console.log(tr);
                    tr.remove();

                    // 先删除 ,在判断   剩余的商品全部被选中
                    // a. 每次删除商品之后  判断  如果剩余的商品全部被选中 => 全选框 变为选中状态
                    // var flag = true;
                    // for (let i = 0; i < checkOneList.length; i++) {
                    //     let checkOne = checkOneList[i];
                    //     if (!checkOne.checked) {
                    //         flag = false;
                    //         break;
                    //     }
                    // }
                    // checkAll.checked = flag;

                    checkAll.checked = isCheckAll();
                    getTotal();// 结算

                }
            }
        }


        // 多删  删除选中的商品

        //数组坍塌
        //      0        1        2       3
        //  [checkOne,checkOne,checkOne,checkOne]
        deleteAll.onclick = function () {
            // a. 找到所有的单选框中 为 选中状态的单选框 => tr  =>删除

            for (let i = 0; i < checkOneList.length; i++) {
                let checkOne = checkOneList[i];
                if (checkOne.checked) {
                    var tr = parent(parent(checkOne));
                    tr.remove();
                    i--;
                }
            }

            checkAll.checked = false;
            // checkAll.checked = isCheckAll();

            getTotal();// 结算

        }
















        // 加号事件
        for (let i = 0; i < addList.length; i++) {
            let add = addList[i];
            add.onclick = function () {
                // console.log(this);
                // a. 输入框  数量 加一 
                var countInput = prev(this);  // 找到加号前的 countInp
                // console.log(countInput);

                var num = countInput.value;  //取值
                num++;  //自增

                countInput.value = num;  //放回去

                // b.  小计更新    =  单价*数量
                // 数量 已经有了
                // 单价 

                var parentTd = parent(this);   // 找到加号的parentTd
                var priceTd = prev(parentTd);  //  parentTd前面的priceTd(价格)
                var subtotalTd = next(parentTd);  //  parentTd前面的subtotalTd
                console.log(priceTd, subtotalTd);

                var price = priceTd.textContent * 1;

                subtotalTd.textContent = (price * num).toFixed(2);

                // 3. 减号按钮的 “-”  出现
                var reduce = prev(countInput);
                reduce.textContent = "-";
                reduce.style.cursor = "pointer";
                getTotal();// 结算

            }
        }



        // 减号事件
        for (let i = 0; i < reduceList.length; i++) {
            let reduce = reduceList[i];
            reduce.onclick = function () {

                // a. 输入框  数量 减一 

                var countInp = next(this);
                var num = countInp.value;
                // c.  减之前  判断  如果数量为1  不能减
                if (num == 1) {
                    console.log("亲,不能在减了");
                    return false;
                }

                num--;  //自减
                // d 减之后  判断  如果数量为1  减号按钮的 “-” 消失  手势禁止
                if (num == 1) {  // 由2变为1的一瞬间
                    this.textContent = "";
                    this.style.cursor = "no-drop";
                }

                countInp.value = num;

                // b.  小计更新    =  单价*数量
                // 数量 已经有了
                // 单价 

                var parentTd = parent(this);   // 找到加号的parentTd
                var priceTd = prev(parentTd);  //  parentTd前面的priceTd(价格)
                var subtotalTd = next(parentTd);  //  parentTd前面的subtotalTd
                console.log(priceTd, subtotalTd);

                var price = priceTd.textContent * 1;

                subtotalTd.textContent = (price * num).toFixed(2);
                getTotal();// 结算
            }
        }



















        // 全选功能
        // 所有的单选 跟随全选的状态

        checkAll.onclick = function () {
            var status = this.checked;
            console.log(status);
            for (var i = 0; i < checkOneList.length; i++) {
                var checkOne = checkOneList[i];
                checkOne.checked = status;
            }
            getTotal();// 结算
        }

        // 反选功能
        // 每次点击单选  都要进行判断  所有的单选是否都选中
        // 如果所有的单选选中 全选也需要改为选中状态 
        // 只要有一个未选中  则 全选不选

        // 循环绑定事件
        for (let i = 0; i < checkOneList.length; i++) {
            let checkOne = checkOneList[i];
            checkOne.onclick = function () {

                // var flag = true;  //假设全被选中
                // for (let i = 0; i < checkOneList.length; i++) {
                //     let checkOne = checkOneList[i];
                //     if (!checkOne.checked) { //checkOne.checked == false   存在未被选中的
                //         flag = false;
                //         break;
                //     }
                // }
                checkAll.checked = isCheckAll();

                getTotal();// 结算

            }
        }


        function isCheckAll() {
            var flag = true;  //假设全被选中
            for (let i = 0; i < checkOneList.length; i++) {
                let checkOne = checkOneList[i];
                if (!checkOne.checked) { //checkOne.checked == false   存在未被选中的
                    flag = false;
                    break;
                }
            }

            // 2.  商品全部删除之后 (bug  商品全部删除之后  全选框依旧被选中)
            //     原因 (isCheckAll  封装时用的是假设法   商品全部删除之后,checkOneList为0 循环不会执行  flag依旧为true)
            //     解决方法  加一个长度判断   如果checkOneList为0(没有商品)  全选框取消全选

            flag = checkOneList.length == 0 ? false : flag;
            return flag;
        }

        // 结算
        function getTotal() {
            // 每次点击单选  将选中的单选框对应的商品数量和小计累加 =>结算
            var sum = 0;
            var allPrice = 0;

            for (let i = 0; i < checkOneList.length; i++) {
                let checkOne = checkOneList[i];
                if (checkOne.checked) { //被选中
                    var parentTr = parent(parent(checkOne));
                    // console.log(parentTr);
                    var countInput = parentTr.getElementsByClassName("count-input")[0];
                    var subtotalTd = parentTr.getElementsByClassName("subtotal")[0];
                    var num = countInput.value * 1;
                    var subtotal = subtotalTd.textContent * 1

                    sum += num;
                    allPrice += subtotal;

                }
            }

            console.log(sum, allPrice);
            selectedTotal.textContent = sum;
            priceTotal.textContent = allPrice.toFixed(2);
        }


        function parent(ele) {
            return ele.parentElement || ele.parentNode;
        }
        function prev(ele) {
            return ele.previousElementSibling || ele.previousSibling;
        }
        function next(ele) {
            return ele.nextElementSibling || ele.nextSibling;
        }




    </script>

    </html>
     
     
    以上就是完整代码啦!感兴趣的朋友可以看看哟!! (哈哈哈哈 来自一个菜鸟的得瑟!)
  • 相关阅读:
    JQuery-文档处理&选择器
    JQuery-事件(部分)
    JS中构造函数与函数
    JS中的String.Math.Date
    JS中的_proto_(2)
    JS中的_proto_
    JS中的constructor
    mysql 安装问题
    【转】SpringMVC中DispatcherServlet配置中url-pattern 配置/*和/的区别
    【转】MySql中的函数
  • 原文地址:https://www.cnblogs.com/yujiawen/p/14096571.html
Copyright © 2011-2022 走看看