思路

思路.png

image.png

image.png

数据驱动思想—-给每个按钮进行绑定点击

HTML

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>购物车计算器</title>
  8. <link rel="stylesheet" href="css/index.css">
  9. </head>
  10. <body>
  11. <div class="box">
  12. <div class="top" id="top">
  13. <!-- <ul>
  14. <li>
  15. <i class="minus"></i>
  16. <span class="pronum">0</span>
  17. <i class="add"></i>
  18. <span class="info">
  19. 单价:12.5元 小计:0元
  20. </span>
  21. </li>
  22. </ul> -->
  23. </div>
  24. <div class="bottom" id="bottom">
  25. <!-- 商品共合计:<span class="pronum num">0</span>件
  26. 共花费了:<span class="pronum num">0</span>元 <br><br>
  27. 其中最贵的商品单价是<span class="pronum num">0</span>元 -->
  28. </div>
  29. </div>
  30. <script src="js/index.js"></script>
  31. </body>
  32. </html>

CSS

*{
    margin: 0;
    padding: 0;
}

ul{
    list-style: none;
}

.box{
    width: 479px;
    height: 591px;
    margin: 0 auto;
    background-image: url(../img/bg1.png);
}


.top{
    padding-top:50px;
    padding-left: 20px;
    height: 387px;
}


/* 减号 */
.minus,.add{
    display: inline-block;
    width: 52px;
    height: 44px;
    background-image: url(../img/sub.png);
    vertical-align: top;
    cursor:pointer;
}

/* 加号 */
.add{
    background-image: url(../img/add.png);
}

.pronum,.info{
    display: inline-block;
    height: 35px;
    width: 50px;
    background-color: white;
    border-radius: 5px;
    line-height:35px;
    text-align: center;
    vertical-align: top;  /*基线对齐*/
    margin-right: 10px;
}


.info{
    background: #171818;
    width: 200px;
    color:white;
    margin-left: 40px;
    text-align: left;
    padding-left: 20px;
}

.bottom{
    padding-top: 20px;
    padding-left: 50px;
    color:#878787;
}

.num{
    vertical-align: middle; 
    margin-left: 10px;
}

JS

// 1.用AJAX获取数据
// 2.把获取的数据渲染到页面上
// 3.获取元素:绑定点击事件,处理数据
let carModel = (function () {
    const getData = function getData() {
        let xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", "json/data2.json");
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
                let data = JSON.parse(xmlHttp.responseText);
                render(data);
                // sendEle(data); 放在这里 仅仅是getData()执行了一次
            }
        };
        xmlHttp.send();
    };
    const render = function render(data) {
        // data是用来渲染DOM的数据
        let top = document.getElementById("top"),
            bottom = document.getElementById("bottom");

        let total = 0,//一共买啦多少件
            totalMoney = 0,//一共花了多少钱
            ary = [];//最贵的商品 买过的商品单价
        let topStr = '<ul>';
        let bottomstr = '';
        data.forEach(item => {
            let { id, count, price } = item;
            total += count;
            totalMoney += count * price;//数量*单价
            count > 0 ? ary.push(price) : null;//当count大于0 则是买过的

            //top数据渲染
            topStr += `<li>
                            <i class="minus" data-id='${id}'></i>
                            <span class="pronum">${count}</span>
                            <i class="add" data-id='${id}'></i>
                            <span class="info">
                                单价:${price}元 小计:${(count * price).toFixed(2)}元
                            </span>
                        </li>`;
        });
        topStr += '</ul>';
        bottomstr += `商品共合计:<span class="pronum num">${total}</span>件 
        共花费了:<span class="pronum num">${totalMoney.toFixed(2)}</span>元 <br><br>
        其中最贵的商品单价是<span class="pronum num">${ary.length > 0 ? Math.max(...ary).toFixed(2) : '0.00'}</span>元`;
        top.innerHTML = topStr;
        bottom.innerHTML = bottomstr;
        sendEle(data);

    };

    const sendEle = function sendEle(data) {
        // let btns=document.querySelectorAll('#top ul li>i');
        let btns = document.getElementsByTagName('i');
        // [].forEach.call(btns,(item)=>{
        // 强制让btns这个类数组使用forEach,通过call改变改变this,来使用
        // });
        // 类数组转数组的几种办法
        //    +Array.from(btns) btns转成数组
        //    +btns=[...btns];//展开运算符
        //    +btns=[].slice.call(btns) =》相当于btns.slice()
        btns = Array.from(btns);
        btns.forEach(ele => {
            ele.onclick = function () {
                // 判断当前元素
                let className = this.className;
                let id = this.getAttribute('data-id');
                data.forEach(item => {
                    //判断当前的那一行
                    if (item.id === +id) {
                        // 用所用item的id和行内获取到的id进行比较 找到我们点击的那个
                        // 减号
                        if (className === "minus") {
                            item.count < 0 ? null : item.count--;
                        } else {
                            //加号操作
                            item.count++;
                        }
                    }
                })
                render(data);
            };
        });
    }
    //绑定点击事件
    return {
        init() {
            getData();
        }
    }
})();

carModel.init();

数据驱动—事件冒泡 跟按钮的父级元素绑定click

HTML

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>购物车计算器</title>
    <!-- IMPORT CSS -->
    <link rel="stylesheet" href="index.css" />
</head>

<body>
    <div class="box" id="computedBox">
        <!-- <div class="top">
            <div class="hang">
                <i class="minus"></i>
                <span class="pronum">2</span>
                <i class="add"></i>
                <span class="info">单价:12.5元 &nbsp;&nbsp; 小计:0元</span>
            </div>
        </div>
        <div class="bottom">
            商品合计:<span class="pronum">0</span> &nbsp; 件
            <br>
            共花费了:<span class="pronum">0</span> &nbsp; 元
            <br>
            其中最贵的商品单价是:<span class="pronum">0</span> &nbsp; 元
        </div> -->
    </div>

    <!-- IMPORT JS -->
    <script src="index.js"></script>
</body>

</html>

CSS

* {
    margin: 0;
    padding: 0;
}

.box {
    margin: 0 auto;
    width: 480px;
    height: 590px;
    background-image: url(img//bg1.png);
}

/* 按钮 */
.minus,
.add {
    width: 52px;
    height: 44px;
    display: inline-block;
    background-image: url(img/sub.png);
    vertical-align: middle;
    cursor: pointer;
}

.add {
    background-image: url(img/add.png);
}

/* 文本框 */
.pronum,
.info {
    box-sizing: border-box;
    width: 40px;
    height: 35px;
    line-height: 35px;
    background: white;
    border-radius: 3px;
    text-align: center;
    vertical-align: middle;
}

.pronum {
    display: inline-block;
}

/* 头部 */
.top {
    padding: 50px 20px 0;
    height: 387px;
}

.hang {
    margin-bottom: 20px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.hang .info {
    box-sizing: border-box;
    padding: 0 10px;
    width: 260px;
    color: white;
    font-size: 14px;
    text-align: left;
    line-height: 35px;
    background: #171818;
}

.bottom {
    padding-top: 20px;
    color: #878787;
    padding-left: 50px;
    line-height: 40px;
}
.bottom .num{
    width: 80px;
}

js

let computedModel=(function(){
    let computedBox=document.querySelector('#computedBox'),
        data=null;

    // 从服务器获取数据
    const queryData=function queryData(){
        let xhr=new XMLHttpRequest();
        xhr.open("GET","./data.json",false);
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4&&xhr.status===200){
                data=JSON.parse(xhr.responseText);
            }
        };
        xhr.send();
    };

    //根据数据渲染视图
    const render=function render(){
        // let str = ``;
        // str += `<div class="top">
        //     ${data.map(item=>{
        //         return `<div class="hang">
        //             <i class="minus"></i>
        //             <span class="pronum">2</span>
        //             <i class="add"></i>
        //             <span class="info">单价:12.5元 &nbsp;&nbsp; 小计:0元</span>
        //         </div>`;
        //     }).join('')}
        // </div>`;

        let str=`<div class="top">`;
        let totalCount=0,
        totalPrice=0,
        priceArr=[0];
        data.forEach(item=>{
            let {id,count,price}=item;
            totalCount+=count;
            totalPrice+=count*price;
            if(count>0)priceArr.push(price);
            str+=` <div class="hang" data-id="${id}">
                        <i class="minus"></i>
                        <span class="pronum">${count}</span>
                        <i class="add"></i>
                        <span class="info">
                            单价:${price}元 &nbsp;&nbsp; 
                            小计:${(count*price).toFixed(2)}元
                        </span>
                    </div>`;
        });
        str+=`</div>`;



        str+=`<div class="bottom">
                商品合计:<span class="pronum ">${totalCount}</span> &nbsp; 件
                <br>
                共花费了:<span class="pronum num">${totalPrice.toFixed(2)}</span> &nbsp; 元
                <br>
                其中最贵的商品单价是:<span class="pronum num">${Math.max.apply(null,priceArr).toFixed(2)}</span> &nbsp; 元
              </div> `;

        computedBox.innerHTML=str;
    };

    // 点击按钮修改数据
    const handle=function handle(){
        // 点击computedBox中的任何元素,都会把computedBox的点击事件行为触发
        computedBox.onclick=function(ev){
            // 获取事件源:具体操作的元素
            let target=ev.target;
            if(target.tagName==='I'){
                // 先找到当前行对应的数据
                let id= +target.parentNode.getAttribute('data-id'),
                    item=data.find(item=>item.id==id);
                    if(!item) return; //如果没有在数据中找到对应项,后续都不做处理了            
                if(target.className==="minus"){
                    item.count--;
                    if(item.count>0){
                        item.count=0;
                    }
                    render();
                    return;
                }else{
                    item.count++;
                    render();
                }
                // 点击的是加号
            };
        }
    };

    return{
        init(){
            queryData();
            render();
            handle();
        }
    };
})();
computedModel.init();