购物车:

购物车:
数量组件:

class StepNum {
    constructor(parent, data) {
        this._data = data;
        this.num = data.num;
        this.step = 1;
        this.evt = new Event(StepNum.CHANGENUM);
// this.flag = false;
        if (!parent) parent = document.body;
        this.div = this.createDiv(parent);
        this.animate();
    }
    createDiv(parent) {
        if (this.div) return this.div;
        let div = document.createElement('div');
        div.className = 'quantity-form';
        div.evt = new Event(StepNum.CHANGENUM);
        Object.assign(div.style, {
            // fontSize: '0',
            textAlign: 'center',
            position: 'absolute',
            overflow: 'hidden',
        })
        let divCon = document.createElement('div');
        let p1 = document.createElement('p');
        p1.textContent = this.num;
// let p2 = document.createElement('p');
// p2.textContent = 2;
        Object.assign(divCon.style, {
            position: 'absolute',
            top: '0',
            left: '17px',
            width: '47px',
            backgroundColor: '#fff',
            textAlign: 'center',
            fontSize: '13px',
        })
        Object.assign(p1.style, {
            margin: '0',
            lineHeight: '22px',
        })
        divCon.appendChild(p1);
        div.appendChild(divCon);
        this.leftBtn = this.createBtn(div);
        this.leftBtn.className = 'reduce';
        this.leftBtn.textContent = '-';
        this.leftBtn.disabled = this.num>1?false:true;
        // this.leftBtn.disabled = true;
// this.createNumInput(div);
        this.input = this.createNumInput(div);
        this.rightBtn = this.createBtn(div);
        this.rightBtn.className = 'increase';
        this.rightBtn.textContent = '+';
// this.leftBtn.input =  input;
// this.rightBtn.input = input;
        this.leftBtn.divCon = divCon;
        this.rightBtn.divCon = divCon;
        divCon.input = this.input;
        this.input.divCon = divCon;
// divCon.add = true;
        divCon.self = this;
        div.self = this;
        parent.appendChild(div);
        return div;
    }

    setNum(num) {
        this.input.value = num;
        this.num = num;
        this.div.firstElementChild.firstElementChild.textContent = num;
        // this.evt = new Event(StepNum.CHANGENUM);
        // 触发事件,传递参数
        this.evt.data = this._data;
        this.evt.num = num;
        document.dispatchEvent(this.evt);
    }

    createBtn(parent) {
        let btn = document.createElement('button');
        let btnStyle = {
            outline: 'none',
            border: '1px solid #ddd',
            padding: '0',
            height: '22px',
            width: '17px',
            cursor: 'pointer',
            position: 'relative'
        };
        Object.assign(btn.style, btnStyle);
        parent.appendChild(btn);
        btn.addEventListener('click', this.clickHandler);
        this.end = true;
        return btn;
    }

    clickHandler(e) {
        this.divCon.style.opacity = '1';
        if (this.parentNode.self.flag === true) return;
// 隐藏input的value值
        this.parentNode.self.input.value = '';
        this.parentNode.self.input.style.backgroundColor = 'rgba(255,255,255,.3)';
// 点击加减
// 点击 - 就在p的前面增加一个p top 移动到 0px 然后删除最后一个p
// 点击 + 就在p的后面增加一个p top移动到-22px 然后删除第一个p

        if (this === this.parentNode.self.leftBtn) {
// if(this.parentNode.self.num<2){
//     this.disabled = true;
//     return;
// };
            this.divCon.style.top = '-22px';
//     this.divCon.flag = false;
            this.parentNode.self.num--;
            let p2 = document.createElement('p');
            Object.assign(p2.style, {
                margin: '0',
                lineHeight: '22px',
            })
            p2.textContent = this.parentNode.self.num;
            this.divCon.insertBefore(p2, this.divCon.firstElementChild);
            this.divCon.add = false;
            if (this.parentNode.self.num === 1) {
                this.disabled = true;
            }
//
//     this.disabled = false;
//
        } else {
// 点击了+
//     this.divCon.flag = true;
            this.parentNode.self.leftBtn.disabled = false;
            this.parentNode.self.num++;
            let p2 = document.createElement('p');
            Object.assign(p2.style, {
                margin: '0',
                lineHeight: '22px',
            })
            p2.textContent = this.parentNode.self.num;
            this.divCon.add = true;
            this.divCon.appendChild(p2);
// this.divCon.style.top = '-22px';
//     // 1s 后删除
        }
// console.log(this.parentNode.self);
        this.parentNode.self.flag = true;
        // 修改数据
        this.parentNode.self._data.num = this.parentNode.self.num;
        this.parentNode.self._data.sum = Number(this.parentNode.self._data.num)*Number(this.parentNode.self._data.price);
// this.parentNode.self.end = false;
// 抛出

        // this.parentNode.self.evt.data = this.parentNode.self._data;
        // this.parentNode.self.evt.num = num;
        // document.dispatchEvent(this.parentNode.self.evt);
    }

    createNumInput(parent) {
        let input = document.createElement('input');
// input.value = 1;
        Object.assign(input.style, {
            outline: 'none',
            textAlign: 'center',
            padding: '0',
            boxSizing: 'border-box',
            border: '1px solid #ddd',
            height: '22px',
            width: '46px',
            backgroundColor: 'rgba(255,255,255,.3)',
            borderLeftWidth: '0',
            borderRightWidth: '0',
            position: 'relative',
            color: 'rgba(0,0,0,.8)',
            fontSize: '13px'
        }),
            parent.appendChild(input);
        input.addEventListener('blur', this.blurHandler);
        input.addEventListener('focus', this.focusHandler);
        return input;
    }

    focusHandler(e) {
        this.value = '';
        this.style.backgroundColor = 'rgb(255,255,255)';
        this.style.opacity = 1;
        this.divCon.style.opacity = '0';
    }

    blurHandler(e) {
// 改变数据时将数据抛出;
// 是数字 且大于1
        if (isNaN(this.value) || parseInt(this.value) < 1 || !this.value) {
            if(!this.parentNode.self.note){
                this.parentNode.self.note = this.parentNode.self.createNote(this.parentNode.self.div);
                console.log(this.parentNode.self.note);
            }
            this.parentNode.self.note.style.display = 'block';
            this.parentNode.self.setNum(1);
// this.value = 1;
            this.parentNode.self.leftBtn.disabled = true;
        } else if (this.value === '1') {
            this.parentNode.self.setNum(1);
            this.parentNode.self.leftBtn.disabled = true;
        } else {
            this.parentNode.self.setNum(this.value);
            this.parentNode.self.leftBtn.disabled = false;
        }
    }

    createNote(parent, text = '商品数量超限') {
        if(this.note) return this.note;
        let div = document.createElement('div');
        Object.assign(div.style, {
            backgroundColor: '#fff',
            border: '1px solid #ddd',
            textAlign: 'center',
            position: 'fixed',
            zIndex: '1000',
            transform: 'translate(-50%,-50%)',
            left: '50%',
            top: '50%',
            display:'none'
        })
        let p = document.createElement('p');
        p.textContent = text;
        p.style.margin = '60px 60px 0';

        let pCon = document.createElement('p');
        pCon.style.margin = '40px';

        let a = document.createElement('a');
        a.addEventListener('click', function () {
            this.parentElement.parentElement.style.display = 'none';
        })
        Object.assign(a.style, {
            textDecoration: 'none',
            backgroundColor: 'red',
            display: 'inline-block',
            padding: '10px 20px',
            color: 'rgb(255, 255, 255)',
        })
        a.href = 'javascript:;';
        a.textContent = '知道了';
        Object.assign(a.style, {
            backgroundColor: 'red',
            padding: '10px 20px',
            color: '#fff',
        })
        pCon.appendChild(a);
        div.appendChild(p);
        div.appendChild(pCon);
        parent.appendChild(div);
        return div;
    }

    static get CHANGENUM() {
        return 'changenum';
    }

    animate() {
        requestAnimationFrame(this.animate.bind(this));
// 当点击了按钮时 改变flag;
        if (!this.flag) return;
        if (this.div.firstElementChild.add) {
// +
            if (this.div.firstElementChild.offsetTop <= -22) {
                console.log('滚动结束');
                this.flag = false;
                this.div.firstElementChild.firstElementChild.remove();
                this.div.firstElementChild.style.top = '0';
                this.div.evt.data = this._data;
                this.div.evt.num = this.div.firstElementChild.firstElementChild.textContent;
                document.dispatchEvent(this.div.evt);
                return;
            }
            this.div.firstElementChild.style.top = this.div.firstElementChild.offsetTop - this.step + 'px';
        } else {
// -
            if (this.div.firstElementChild.offsetTop >= 0) {
                this.flag = false;
                this.div.firstElementChild.lastElementChild.remove();
                this.div.firstElementChild.style.top = '0';
                this.div.evt.data = this._data;
                this.div.evt.num = this.div.firstElementChild.firstElementChild.textContent;
                document.dispatchEvent(this.div.evt);
                return;
            }
            this.div.firstElementChild.style.top = this.div.firstElementChild.offsetTop + this.step + 'px';
        }
    }
}

购物列表:

class GoodsItem{
   constructor(_props,parent){
      this.prop = _props;
      this.goods=this.initGoods(parent);
      this.render(_props);
   }
   initGoods(parent){
      if(this.goods) return this.goods;
      let div=document.createElement("div");
      Object.assign(div.style,{
         width: "290px",
         height: "390px",
         marginLeft: "10px",
         marginBottom: "20px",
         backgroundColor: "white",
         position: "relative",
         float:"left"
      });
      this.createImgGoods(div);
      this.createPriceCon(div);
      parent.appendChild(div);
      return div;
   }
   createImgGoods(parent){
      let div=document.createElement("div");
      Object.assign(div.style,{
         textAlign: "center",
         height: "330px",
         width: "100%",
         position: "relative"
      });
      this.goodsImg=new Image();
      Object.assign(this.goodsImg.style,{
         width:'85%',
         marginTop: "20px",
         transition: "all 1s",
      });
      this.goodsInfo=document.createElement("p");
      Object.assign(this.goodsInfo.style,{
         fontSize: "14px",
         width: "230px",
         overflow: "hidden",
         height: "40px",
         left: 0,
         right: 0,
         margin: "auto",
         position: "absolute",
         lineHeight: "22px",
         bottom: "10px"
      });
      div.appendChild(this.goodsImg);
      div.appendChild(this.goodsInfo);
      div.addEventListener("mouseenter",this.mouseHandler);
      div.addEventListener("mouseleave",this.mouseHandler);
      parent.appendChild(div);
   }
   createPriceCon(parent){
      let div=document.createElement("div");
      Object.assign(div.style,{
         border: "2px solid #e01222",
         height: "58px",
         width: "286px",
         bottom: 0,
         position: "absolute"
      });
      let priceDiv=document.createElement("div");
      this.goodsBn=document.createElement("div");
      Object.assign(this.goodsBn.style,{
         width: "87px",
         height: "58px",
         position: "absolute",
         right: 0,
         top:0,
         color: "white",
         fontSize: "16px",
         textAlign: "center",
         lineHeight: "58px",
         cursor: "pointer",
         backgroundColor: "#e01222"
      });
      this.goodsBn.textContent="立即抢购";
      this.goodsBn.self = this;
      this.createPriceDiv(priceDiv);
      div.appendChild(priceDiv);
      div.appendChild(this.goodsBn);
      this.goodsBn.addEventListener("click",this.clickHandler);

      parent.appendChild(div);
   }
   createPriceDiv(parent){
      let priceDivs=document.createElement("div");
      let soldDivs=document.createElement("div");
      this.nowPrice=document.createElement("span");
      this.initPrice=document.createElement("span");
      priceDivs.appendChild(this.nowPrice);
      priceDivs.appendChild(this.initPrice);
      this.percent=document.createElement("span");
      let percentCon=document.createElement("span");
      this.soldPercent=document.createElement("span");
      percentCon.appendChild(this.soldPercent);
      soldDivs.appendChild(this.percent);
      soldDivs.appendChild(percentCon);
      Object.assign(this.percent.style,{
         fontSize: "16px",
         marginLeft:"10px",
         lineHeight:"10px"
      });
      Object.assign(this.nowPrice.style,{
         fontSize: "24px",
         color: "#e01222",
         marginLeft: "5px",
         lineHeight: "35px"
      });
      Object.assign(this.initPrice.style,{
         fontSize: "14px",
         textDecoration: "line-through",
         marginLeft: "5px"
      });
      Object.assign(percentCon.style,{
         display: "inline-block",
         width: "100px",
         height: "10px",
         border: "1px solid #e01222",
         marginLeft:"20px",
         marginTop:"5px",
         position: "absolute"
      });
      Object.assign(this.soldPercent.style,{
         position: "absolute",
         width: "0%",
         height: "10px",
         top:0,
         bottom: 0,
         backgroundColor: "#e01222"
      });
      parent.appendChild(priceDivs);
      parent.appendChild(soldDivs);
   }
   mouseHandler(e){
      if(e.type==="mouseenter"){
         this.firstElementChild.style.marginTop="0px";
      }else if(e.type==="mouseleave"){
         this.firstElementChild.style.marginTop="20px";
      }
   }
   clickHandler(e){
      // 点击添加购物车,这里是要向外抛发事件,并且用event将数据传出;
      let evt = new Event(GoodsItem.ADD_SHOPPING_CAR);
      evt.data = this.self.prop;
      document.dispatchEvent(evt);
   }
   render(_props){
      this.goodsImg.src=_props.icon;
      this.goodsInfo.textContent=_props.goods;
      this.nowPrice.textContent="¥"+_props.nowPrice;
      this.initPrice.textContent="¥"+_props.initPrice;
      this.goodsBn.id=_props.id;
      if(_props.sold>1) return;
      this.percent.textContent=(_props.sold*100).toFixed(2)+"%";
      this.soldPercent.style.width=_props.sold*100+"%";

   }
   static get ADD_SHOPPING_CAR(){
      return 'add_shopping_car';
   }
}

购物页面:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>类与其他之间的事件抛发</title>
    <script src="./goodItem.js"></script>
    <scrip src="./stepNum.js"></scrip>
</head>
<body>
    <div>
        <button>
            进入购物车
        </button>
<!--        <a href='' target="_blank">进入购物车</a>-->
    </div>
<script>
    let shoppinglist = [];
    let data=[
        {id:1001,icon:"imgs/03.jpg",goods:"德国DMK进口牛奶 欧德堡(Oldenburger)超高温处理全脂纯牛奶1L*12盒",info:"1L*12",nowPrice:139,initPrice:156,sold:0.5},
        {id:1002,icon:"imgs/04.jpg",goods:"帮宝适(Pampers)超薄干爽绿帮纸尿裤L164片(9-14kg)大码 尿不湿箱装",info:"L【9-14kg】",nowPrice:225,initPrice:275,sold:0.5},
        {id:1003,icon:"imgs/05.jpg",goods:" 意大利进口 百乐可(BALOCCO) 千层酥饼 脆皮酥薄脆饼干 焦糖味 200g",info:"焦糖脆皮酥200g",nowPrice:27.9,initPrice:40,sold:0.5},
        {id:1004,icon:"imgs/06.jpg",goods:"百草味 坚果零食干果 每日坚果 奶油味夏威夷果200g/袋(内含开果器)",info:"夏威夷果奶油味200g/袋",nowPrice:16.9,initPrice:30,sold:0.5},
        {id:1005,icon:"imgs/07.jpg",goods:"三星 Galaxy S10 8GB+512GB炭晶黑(SM-G9730)3D超声波屏下指纹超感官全视屏骁龙855双卡双待全网通4G游戏手机 ",info:"炭晶黑\n8GB+512GB",nowPrice:7699,initPrice:9899,sold:0.5},
        {id:1006,icon:"imgs/01.jpg",goods:"罗技(G)G102 游戏鼠标 8000DPI RGB鼠标 黑色 吃鸡鼠标 绝地求生",info:"G102有线游戏鼠标 黑色",nowPrice:119,initPrice:146,sold:0.5},
        {id:1007,icon:"imgs/02.jpg",goods:"联想(Lenovo)拯救者Y7000英特尔酷睿i5 15.6英寸游戏笔记本电脑( i5-8300H 8G 512G SSD GTX1050 黑)",info:"Y7000【1050 i5 512",nowPrice:5699,initPrice:6200,sold:0.5}
    ];
    let drag = document.createDocumentFragment();
    for(let i =0;i<data.length;i++){
        let good = new GoodsItem(data[i],drag);
    }
    document.body.appendChild(drag);
    document.addEventListener(GoodsItem.ADD_SHOPPING_CAR,addcarHandler)
    function addcarHandler(e) {
        // 添加商品
        let prop = e.data;
        // 如果商品id存在
        let item = shoppinglist.filter((i)=>{
            return i.id === prop.id;
        })
        // 找不到值返回空数组
        if(!item.length){
            let good = {
                selected:false,
                id:prop.id,
                icon:prop.icon,
                goods:prop.goods,
                info:prop.info,
                price:prop.nowPrice,
                num:1,
                sum:prop.nowPrice,
                delete:false
            }
            shoppinglist.push(good);
        }else{
            // 浅拷贝
            item[0].num++;
        }
        //  渲染商品购物车
    }
    let a = document.querySelector('button');
    a.addEventListener('click',clickEvent);
    function clickEvent(e) {
        let url = 'carpage.html?list='+encodeURI(JSON.stringify(shoppinglist));
        location.href = url;
    }
</script>
</body>
</html>

购物车表格:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>购物车页面</title>
    <script src="stepNum.js"></script>
    <style>
        table td{
            /*display: inline-block;*/
        }
    </style>
</head>
<body>
<script>
    let url = location.search;
    let deUrl = decodeURI(url)
    let data =JSON.parse(deUrl.split('?')[1].split('=')[1]);
    let table;
    let tdWidth = [40,82,220,170,160,80,140,75];
    let inputs;
    init();
    function init() {
        clearTable(table);
        table = createTable(document.body,data);
        inputs = document.querySelectorAll('input[type="checkbox"]');
        document.addEventListener(StepNum.CHANGENUM,stepNumHandler);
    }

    function stepNumHandler(e) {
        // 在data中找到e.data,修改里面的num
        data.forEach((i)=>{
            if(i.id === e.data.id){
                i.num = e.data.num;
                i.sum = e.data.sum;
            }
        })
        clearTable(table);
        table = createTable(document.body,data);
    }
    function createTable(parent,data) {
        let table = document.createElement('table');
        Object.assign(table.style,{
            borderCollapse:'collapse',
            border:'1px solid #ddd',
            width:'990px'
        })
        createTableHead(table);
        createTableBody(table,data);
        parent.appendChild(table);
        return table;
    }
    function createTableBody(parent,data) {
        let fragment = document.createDocumentFragment();
        for(let i =0;i<data.length;i++){
            let tr = document.createElement('tr');
            Object.assign(tr.style,{
                verticalAlign: 'top',
                border: '1px solid #ddd',
                backgroundColor: 'antiquewhite',
                fontSize: '13px'
            })
            for(let prop in data[i]){
                if(prop === 'id')continue;
                let td = document.createElement('td');
                td.style.textAlign = 'center';
                td.style.padding = '20px 0';
                switch (prop) {
                    case 'selected':
                        let input = document.createElement('input');
                        input.type = 'checkbox';
                        input.checked = data[i][prop];
                        input.addEventListener('click',inputSelectHandler)
                        Object.assign(input.style,{
                            verticalAlign: 'baseline',
                            height: '10px',
                            marginRight: '20px',
                            marginLeft:'10px',
                            textAlign:'left',
                        })
                        td.appendChild(input);
                        td.style.width = '60px';
                        td.style.textAlign = 'left';
                        break;
                        case 'icon':
                            let img = new Image();
                            img.src = data[i][prop];
                            img.width = 100;
                            td.appendChild(img);
                            td.style.textAlign = 'left';
                            td.style.width = '200px';
                        break;
                        case 'num':
                            // parent,data
                            let stepNum = new StepNum(td,data[i]);
                            Object.assign(td.style,{
                                width: '80px',
                                textAlign: 'center'
                            })
                        break;
                        case 'sum':
                            td.style.width = '100px';
                        case 'price':
                            td.textContent ='¥'+data[i][prop].toFixed(2);
                            break;
                        case 'delete':
                            td.textContent = '删除';
                            td.style.padding='20px';
                            td.addEventListener('click',delHandler);
                            td.style.cursor = 'pointer';
                        break;
                        case 'goods':
                            data[i][prop]=data[i][prop].slice(0,36);
                            td.style.width = '200px';
                            td.textContent = data[i][prop];
                            td.style.textAlign = 'left';
                            break;
                        default:
                            td.textContent = data[i][prop];
                            break;
                }
                tr.appendChild(td);
            }
            fragment.appendChild(tr);
        }
        parent.appendChild(fragment);
    }
    function inputSelectHandler(e) {
        let flag = true;
        for(let i =1;i<inputs.length;i++){
            if(inputs[i].checked === false){
                flag = false;
                break;
            }
        }
        inputs[0].checked = flag;
    }
    function delHandler(e) {
        // 将data中对应的datalist 删除
        let trs = Array.from(table.children);
        let idx = trs.indexOf(this.parentNode);
        data = data.filter((i,index)=>{
            return index !== idx-1;
        })
        this.parentNode.remove();
    }
    function createTableHead(parent) {
        let thlist = ['全选','商品','单价','数量','小计','操作'];
        let tr = document.createElement('tr')
        for(let i =0;i<thlist.length;i++){
            let th = document.createElement('th');
            Object.assign(th.style,{
                textAlign:'center',
                padding:'10px 0',
                fontSize:'14px',
                fontWeight:'normal'
            })
            if(thlist[i]==='商品'){
                th.colSpan = 2;
                th.style.textAlign = 'left';
            }
            th.textContent = thlist[i];
            if(thlist[i]==='全选'){
                let selectAll = document.createElement('input');
                selectAll.addEventListener('click',selectAllHandler);
                selectAll.type = 'checkbox';
                Object.assign(selectAll.style,{
                    verticalAlign: 'baseline',
                    height: '10px',
                    marginRight: '20px',
                    marginLeft:'10px'
                })
                th.colSpan = 2;
                th.style.textAlign = 'left';
                th.insertBefore(selectAll,th.firstChild);
            }
            tr.appendChild(th);
        }
        parent.appendChild(tr);
    }
    function selectAllHandler(e) {
        // let inputs = document.querySelectorAll('input[type="checkbox"]');
        for(let i =1;i<inputs.length;i++){
            inputs[i].checked = this.checked;
        }
    }
    function clearTable(table) {
        if(table){
            table.remove();
        }
    }
</script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值