原生js实现购物车添加删除商品、计算价格功能

购物车

功能需求:

  1. 根据数据创建购物车内容;
  2. 实现购物车添加商品功能;
  3. 实现购物车商品数量的增加、减少;
  4. 实现购物车商品的删除功能;
  5. 购物车的全选功能;
  6. 底部计算总件数、总价;

看一下效果:

原生js实现购物车添加删除商品、计算价格功能
分析:

  • 分了三个文件来写,GoodsList.js,用来创建商品列表;ShoppingCart.js,用来创建购物车内容,StepNumber.js,用来创建购物车中,操作商品数量的组件。
  • 要分清各个页面之间的通信。
  • 案例中,购物车数据为shopCartArr,所以任何有关数据的操作,最好是在同一个文件内,以保证数据的同步。不管是在哪个文件进行的操作,统一将数据抛发到 Html 文件里,对数据进行操作。
  • 类是可以进行实例化的,不建议在类文件中给元素添加 id 属性,因为当实例化多个类时,页面上会出现多个相同的 id,违反了 id 属性的唯一性。
  • 在给 input 设置属性时,如果使用的是 innerHTML 方法,input 的某些属性可能会出现设置不功能的现象,可以使用DOM元素来操作。

下面附上代码:

html文件,模拟数据,监听各个文件的抛发事件,对数据进行操作:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>shoppingCart</title>
</head>
<body>
    <script type="module">
        import GoodsList from './js/GoodsList.js';
        import ShoppingCart from './js/ShoppingCart.js';
        let ADD_GOODS_EVENT="add_goods_event";
        let DELETE_EVENT="delete_event";
        let STEP_CHANGE_EVENT="step_change_event";
        let CHECKED_EVENT="checked_event";
        //监听添加商品事件
        document.addEventListener(ADD_GOODS_EVENT,addGoodsEvent);
        //监听删除商品事件
        document.addEventListener(DELETE_EVENT,deleteEvent);
        //监听改变商品数量事件
        document.addEventListener(STEP_CHANGE_EVENT,stepChangeEvent);
        //监听点击多选框事件
        document.addEventListener(CHECKED_EVENT,checkedEvent);
        //模拟商品列表数据
        var arr=[
            {id:"0001",img:"img01.webp",title:"不知火丑柑丑橘5斤装",desc:"第二件9.9元",price_desc:"1年历史最低价",price_now:"19.9",price_pre:"29.9",sale:"511",href:"https://item.jd.com/21562085787.html",weight:"2.5",state:"1"},
            {id:"0006",img:"img06.webp",title:"全母盛宴(2.0-2.3两)10只",desc:"现捕现发",price_desc:"82天历史最低价",price_now:"98",price_pre:"189",sale:"35",href:"https://item.jd.com/60387540668.html",weight:"0.3",state:"0"},
            {id:"0007",img:"img07.webp",title:"态好吃100%纯可可脂黑巧克力",desc:"买一送一丝滑细腻",price_desc:"181天历史最低价",price_now:"17.9",price_pre:"29.9",sale:"150",href:"https://item.jd.com/50895183185.html",weight:"0.12",state:"1"},
            {id:"0010",img:"img10.webp",title:"买一送一雪媚娘蛋黄酥330g/盒",desc:"买一送一共12枚",price_desc:"1年历史最低价",price_now:"27.8",price_pre:"39.8",sale:"292",href:"https://item.jd.com/25665431802.html",weight:"0.33",state:"1"},
            {id:"0011",img:"img11.webp",title:"五常有机稻花香500g(1斤)",desc:"正宗五常大米",price_desc:"138天历史最低价",price_now:"19.9",price_pre:"29.9",sale:"10",href:"https://item.jd.com/56090150750.html",weight:"0.5",state:"1"},
            {id:"0012",img:"img12.webp",title:"湖南毛毛鱼 小鱼干20包 糖醋",desc:"2件8折3件7折",price_desc:"230天历史最低价",price_now:"13.9",price_pre:"19.9",sale:"103",href:"https://item.jd.com/49202317748.html",weight:"0.15",state:"1"},
        ]
        //购物车列表数据
        var shopCartArr=[];
        //创建商品列表
        setGoodsList();
        function setGoodsList(){
            let div=document.createElement("div");
            div.className="clearfix";
            for(let i=0;i<arr.length;i++){
                let main = new GoodsList(arr[i],"./img/");
                main.appendTo(div);
            }
            document.body.appendChild(div);
        }
        //添加商品
        function addGoodsEvent(e){
            let arr=shopCartArr.filter(item=>item.id===e.list.id);
            if(arr.length===0){
                //如果该商品是第一次添加,执行下面的操作
                let data={
                    id:e.list.id,
                    //如果商品不可售卖,checked设为false
                    checked:e.list.state==1?true:false,
                    img:e.list.img,
                    title:e.list.title,
                    price:Number(e.list.price_now).toFixed(2),
                    num:1,
                    weight:e.list.weight,
                    subWeight:e.list.weight,
                    //state为1时,表示商品可售卖,为0时,表示不可售卖
                    state:e.list.state,
                    subPrice:Number(e.list.price_now).toFixed(2),
                    href:"https://item.jd.com/21562085787.html"
                }
                shopCartArr.push(data);
            }else{
                //如果该商品不是第一次添加,更改商品的数量
                arr[0].num++;
                arr[0].subWeight=(arr[0].num*arr[0].weight).toFixed(2);
                arr[0].subPrice=(arr[0].num*arr[0].price).toFixed(2);
            }
            //重新获取购物车数据
            setshoppingCart();
        }
        function deleteEvent(e){
            //删除商品
            shopCartArr=shopCartArr.filter(item=>item.id!==e.data.id);
            //重新获取购物车数据
            setshoppingCart();
        }
        function stepChangeEvent(e){
            //更改商品的数量、小计和重量
            shopCartArr.forEach(item=>{
                if(item.id===e.data.id){
                    item.num=e.num;
                    item.subPrice=(item.num*item.price).toFixed(2);
                    item.subWeight=(item.num*item.weight).toFixed(2);
                }
            })
            //重新获取购物车数据
            setshoppingCart();
        }
        function checkedEvent(e){
            if(e.data==="all"){
                //如果点击的是全选按钮
                shopCartArr.forEach(item=>{
                    //改变可售卖商品前面的checkbox状态
                    if(item.state==1) item.checked=e.tag.checked;
                })
            }else{
                //如果点击的是某个商品的checkbox,只改变它的checked值
                shopCartArr.forEach(item=>{
                    if(item.id===e.data.id) item.checked=e.tag.checked;
                })
            }
            //重新获取购物车数据
            setshoppingCart();
        }

        var shoppingCart;
        //创建购物车内容
        function setshoppingCart(){
            if(shoppingCart){
                //删除之前购物车的内容,重新创建
                shoppingCart.elem.remove();
                shoppingCart.elem=null;
            }
            shoppingCart=new ShoppingCart(shopCartArr);
            shoppingCart.appendTo("body");
        }
    </script>
</body>
</html>

ShoppingCart.js文件,创建购物车内容,操作购物车DOM元素时抛发事件:

import Utils from "./Utils.js";
import StepNumber from "./StepNumber.js";
export default class ShoppingCart{
    static styles=false;
    static DELETE_EVENT="delete_event";
    static CHECKED_EVENT="checked_event";
    constructor(_list){
        this.list=_list;
        this.elem=this.createE();
    }
    createE(){
        if(this.elem) return this.elem;
        //创建外层容器
        let div=Utils.createE("div");
        div.className="cart_main";
        //创建头部内容
        let cartTh=Utils.createE("div",{},{
            className:"cart_table_th"
        })
        this.createCartTableTh(cartTh);
        Utils.appendTo(cartTh,div);
        //创建购物车主体内容
        let cartCont=Utils.createE("div",{},{
            className:"cart_content"
        })
        this.createShoppingCartCont(cartCont);
        Utils.appendTo(cartCont,div);
        //创建底部总计
        let cartBottom=Utils.createE("div",{},{
            className:"cart_bottom"
        })
        this.createCartBottom(cartBottom);
        Utils.appendTo(cartBottom,div);
        //插入样式
        ShoppingCart.setStyle();
        //计算显示的总计
        this.totalCount();
        return div;
    }
    appendTo(parent){
        Utils.appendTo(this.elem,parent);
    }
    createCartTableTh(parent){
        //创建头部内容
        let str=`<div class="th th_chk"><label class="cart_checkbox"><span>全选<span></label></div>
        <div class="th th_item">商品信息</div>
        <div class="th th_price">金额</div>
        <div class="th th_amount">数量</div>
        <div class="th th_weight">重量</div>
        <div class="th th_location">&nbsp;</div>
        <div class="th th_sum">小计</div>
        <div class="th th_op">操作</div>`;
        parent.innerHTML=str;
        let input=Utils.createE("input",{},{
            type:"checkbox",
            //全选框的默认值根据state为1的商品来设置
            checked:this.list.filter(item=>item.state==1).every(item=>item.checked)
        })
        //给多选框监听点击事件
        input.addEventListener("click",e=>this.checkboxClickHandler(e,"all"));
        Utils.insertBefore(input,parent.firstElementChild.firstElementChild);
    }
    createShoppingCartCont(parent){
        //创建购物车主体内容
        this.list.forEach(item => {
            let ul=Utils.createE("ul",{
                //如果商品不可售卖,添加灰色背景
                backgroundColor:item.state==0?`#f5f5f5`:"none"
            },{
                className:"item_content clearfix"
            });
            ul.innerHTML=`<li class="td_chk"></li>
            <li class="td_item">
                <div class="item_pic"><a href="${item.href}" target="_blank"><img src="${item.img}"></a></div>
                <div class="item_info"><a href="${item.href}" target="_blank">${item.title}</a></div>
            </li>
            <li class="td_price">${item.price}</li>
            <li class="td_amount"></li>
            <li class="td_weight">${item.subWeight}kg</li>
            <li class="td_location">${item.state==1?"有货":"无货"}</li>
            <li class="td_sum">${item.subPrice}</li>
            <li class="td_op">删除</li>`;
            let input=Utils.createE("input",{},{
                type:"checkbox",
                checked:item.checked,
                //如果商品不可售卖,设置多选框不可点击
                disabled:item.state==0?true:false
            });
            Utils.appendTo(input,ul.firstElementChild);
            //创建step
            let step=this.createStepNumber(item);
            Utils.appendTo(step,ul.firstElementChild.nextElementSibling.nextElementSibling.nextElementSibling);
            //监听删除事件
            ul.lastElementChild.addEventListener("click",()=>this.deleGoodsInfo(item));
            Utils.appendTo(ul,parent);
            //给可售卖商品的多选框监听点击事件
            if(item.state==1) input.addEventListener("click",e=>this.checkboxClickHandler(e,item));
        });
    }
    createStepNumber(obj){
        let stepNumber=new StepNumber(obj);
        return stepNumber.elem;
    }
    createCartBottom(parent){
        //创建底部内容
        let label=Utils.createE("label");
        let input=Utils.createE("input",{},{
            type:"checkbox",
            //全选框的默认值根据state为1的商品来设置
            checked:this.list.filter(item=>item.state==1).every(item=>item.checked)
        })
        //全选框监听点击事件
        input.addEventListener("click",e=>this.checkboxClickHandler(e,"all"));
        Utils.appendTo(input,label);
        Utils.appendTo(Utils.createE("span",{margin:"0px"},{textContent:"全选"}),label);
        Utils.appendTo(label,parent);
        //创建删除按钮
        let delBtn=Utils.createE("a",{},{
            className:"cart_bottom_del",
            textContent:"删除"
        });
        //监听删除事件
        delBtn.addEventListener("click",()=>this.deleGoodsInfo("all"));
        Utils.appendTo(delBtn,parent);
        //创建文字内容
        this.spanNum=Utils.createE("span");
        Utils.appendTo(this.spanNum,parent);
        this.spanWeight=Utils.createE("span");
        Utils.appendTo(this.spanWeight,parent);
        this.spanPrice=Utils.createE("span");
        Utils.appendTo(this.spanPrice,parent);
    }
    totalCount(){
        //总计,初始设置为0
        this.totalPrices=0;
        this.totalWeight=0;
        this.totalNum=0;
        this.list.forEach(item=>{
            if(item.checked){
                //计算选中商品的总计
                this.totalPrices+=Number(item.subPrice);
                this.totalWeight+=Number(item.subWeight);
                this.totalNum+=Number(item.num);
            }
        })
        this.spanPrice.innerHTML=`商品总价<em>¥${this.totalPrices.toFixed(2)}</em>`;
        this.spanWeight.innerHTML=`商品总重:${this.totalWeight.toFixed(2)}kg`;
        this.spanNum.innerHTML=`总共:${this.totalNum}件商品`;
    }
    checkboxClickHandler(e,type){
        //多选框抛发事件
        let evt=new Event(ShoppingCart.CHECKED_EVENT);
        evt.data=type;
        evt.tag=e.target;
        document.dispatchEvent(evt);
    }
    deleGoodsInfo(type){
        //删除商品
        if(type==="all"){
            this.list.forEach(item=>{
                //使用递归循环
                if(item.checked) this.deleGoodsInfo(item);
            })
        }else{
            //删除商品抛发事件
            let evt=new Event(ShoppingCart.DELETE_EVENT);
            evt.data=type;
            document.dispatchEvent(evt);
        }
    }
    static setStyle(){
        if(ShoppingCart.styles) return;
        ShoppingCart.styles=true;
        Utils.insertCss(".cart_main",{
            width:"980px",
            fontSize:"12px",
            color: "#696969",
            background:"#fff",
            margin:"20px auto 0px",
            textAlign:"center",
            userSelect:"none"
        })
        Utils.insertCss(".cart_table_th",{
            height: "34px",
            border: "1px solid #dbdbdb",
            borderBottom:"none",
            height: "34px",
            lineHeight: "34px",
            background: "#f3f3f3",
            color: "#666"
        })
        Utils.insertCss(".cart_table_th .th",{
            float: "left",
            textAlign: "center"
        })
        Utils.insertCss(".cart_table_th .th_chk",{
            width:"58px"
        })
        Utils.insertCss(".cart_checkbox",{
            width: "13px",
            height: "13px",
        })
        Utils.insertCss(".th_item",{
            width:"290px"
        })
        Utils.insertCss(".th_price,.td_price",{
            width:"100px"
        })
        Utils.insertCss(".th_amount,.td_amount",{
            width:"115px"
        })
        Utils.insertCss(".th_weight,.td_weight",{
            width:"70px"
        })
        Utils.insertCss(".th_location,.td_location",{
            width:"137px"
        })
        Utils.insertCss(".th_sum,.td_sum",{
            width:"115px"
        })
        Utils.insertCss(".th_op,.td_op",{
            width:"89px",
            cursor:"pointer"
        })
        Utils.insertCss(".cart_content",{
            border: "1px solid #dbdbdb",
            backgroundColor: "#f3f3f3"
        })
        Utils.insertCss(".item_content",{
            listStyle:"none",
            padding:"0px",
            margin:"0px",
            height:"82px",
            backgroundColor:"#fff",
            borderBottom:"1px solid #dbdbdb"
        })
        Utils.insertCss(".item_content li",{
            paddingTop:"16px",
            float:"left"
        })
        Utils.insertCss(".item_content .td_chk",{
            width: "44px",
            paddingTop:"32px",
        })
        Utils.insertCss(".td_item",{
            width:"308px",
            textAlign:"left"
        })
        Utils.insertCss(".item_pic",{
            width:"60px",
            height:"60px",
            float:"left"
        })
        Utils.insertCss(".item_pic img",{
            width:"60px",
            height:"60px"
        })
        Utils.insertCss(".item_info",{
            float:"left",
            padding:"12px 15px 0 11px",
            width: "220px"
        })
        Utils.insertCss(".item_info a",{
            color:"#666",
            textDecoration:"none"
        })
        Utils.insertCss(".cart_bottom",{
            height:"62px",
            lineHeight:"62px",
            backgroundColor:"#e6e6e6",
            marginTop:"20px",
            textAlign:"left",
            fontSize:"14px"
        })
        Utils.insertCss(".cart_bottom label,.cart_bottom_del,.cart_bottom span",{
            margin:"0px 20px"
        })
        Utils.insertCss(".cart_bottom_del",{
            color:"#696969",
            textDecoration:"none",
            cursor:"pointer"
        })
        Utils.insertCss(".cart_bottom em",{
            color:"#e71a0f",
            fontStyle:"normal",
            fontSize:"18px"
        })
    }
}

StepNumber.js文件,实现点击左右按钮,改变数量的功能:

import Utils from './Utils.js';
export default class StepNumber{
    static styles=false;
    static STEP_CHANGE_EVENT="step_change_event";
    ids;
    constructor(_data){
        this.data=_data;
        this.num=_data.num;
        this.elem=this.createE();
    }
    createE(){
        if(this.elem) return this.elem;
        //创建外层容器
        let div=Utils.createE("div");
        div.className="item_amount clearfix";
        //左边按钮
        let reduceBtn=Utils.createE("a",{},{
            className:"btn_reduce",
            textContent:"-"
        })
        //输入框
        let input=Utils.createE("input",{},{
            className:"amount_inp",
            type:"text",
            value:this.num,
            //如果state为0,设置input不可输入
            disabled:this.data.state==1?false:true
        })
        //右边按钮
        let addBtn=Utils.createE("a",{},{
            className:"btn_add",
            textContent:"+"
        })
        Utils.appendTo(reduceBtn,div);
        Utils.appendTo(input,div);
        Utils.appendTo(addBtn,div);
        //设置样式
        StepNumber.setStyles();
        //给state为1的商品监听点击事件
        if(this.data.state==1) div.addEventListener("click",e=>this.clickHandler(e));
        return div;
    }
    appendTo(parent){
        Utils.appendTo(this.elem,parent);
    }
    clickHandler(e){
        e.preventDefault();
        let target=e.target;
        //如果点击的元素不是a或者input,直接跳出
        if(target.nodeName!=="A"&&target.nodeName!=="INPUT") return;
        if(Utils.hasClass(target,"btn_reduce")){
            //点击左边的按钮
            this.num--;
            this.setStep(target.nextElementSibling);
        }else if(Utils.hasClass(target,"btn_add")){
            //点击右边的按钮
            this.num++;
            this.setStep(target.previousElementSibling);
        }else if(target.nodeName==="INPUT"){
            //点击input,监听input事件
            target.addEventListener("input",e=>this.inputHandler(e));
        }
    }
    inputHandler(e){
        //采用节流,提高效率
        if(this.ids) return;
        this.ids=setTimeout(()=>{
            clearTimeout(this.ids);
            this.ids=0;
            this.setInputsValue(e.target);
        },500);
    }
    setInputsValue(target){
        let value=target.value;
        //禁止输入非数字
        value=value.replace(/\D/g,"");
        //如果input的value为空,让它等于1
        if(value.length===0) value="1";
        this.num=value;
        this.setStep(target);
    }
    setStep(obj){
        //设置值
        if(this.num<=1) this.num=1;
        if(this.num>=999) this.num=999;
        obj.value=this.num;
        //抛发事件
        let evt=new Event(StepNumber.STEP_CHANGE_EVENT);
        evt.num=this.num;
        evt.data=this.data;
        document.dispatchEvent(evt);
    }
    static setStyles(){
        if(StepNumber.styles) return;
        StepNumber.styles=true;
        Utils.insertCss(".item_amount",{
            width:"90px",
            height:"26px"
        })
        Utils.insertCss(".btn_reduce,.btn_add",{
            display:"block",
            float:"left",
            width:"21px",
            height:"21px",
            lineHeight:"21px",
            textAlign:"center",
            border:"1px solid #ccc",
            color:"#696969",
            textDecoration:"none"
        })
        Utils.insertCss(".amount_inp",{
            float:"left",
            width:"32px",
            height:"19px",
            lineHeight:"20px",
            textAlign:"center",
            margin:"0px 4px",
            padding:"0px"
        })
    }
}

GoodsList.js文件,创建商品列表:

import Utils from './Utils.js';
export default class GoodsList {
    static styles=false;
    static ADD_GOODS_EVENT="add_goods_event";
    constructor(_list, basePath) {
        //拼接图片的路径
        if (basePath) _list.img = basePath + _list.img;
        this.list=_list;
        this.elem = this.createElem(_list);
    }
    createElem(_list) {
        if(this.elem) return this.elem;
        let div = Utils.createE("div");
        div.className = "goodsContainer";
        //页面结构
        div.innerHTML = `<a class="goodsInfo" href="${_list.href}" target="_blank">
        <img class="goodsImg" src="${_list.img}" title="${_list.title}">
        <span class="goodsTit">${_list.title}</span>
        <span class="goodsDesc">${_list.desc}</span></a>
        <div class="goodsPrice clearfix"><div class="leftCon">
        <div class="priceDesc">${_list.price_desc}</div><div class="priceNow"><span>¥</span>${_list.price_now}</div>
        <del class="pricePre">¥${_list.price_pre}</del></div>
        <div class="rightCon"><p class="sale">已卖<span>${_list.sale}</span>件</p></div></div>`;
        let a=Utils.createE("a",{},{
            className:"saleBtn",
            textContent:"加入购物车"
        })
        //监听添加商品事件
        a.addEventListener("click",e=>this.addShoppingCartHandler(e))
        Utils.appendTo(a,div.lastElementChild.lastElementChild)
        //写样式
        GoodsList.setStyles();
        return div;
    }
    appendTo(parent) {
        Utils.appendTo(this.elem, parent);
    }
    addShoppingCartHandler(e){
        //抛发事件
        let evt=new Event(GoodsList.ADD_GOODS_EVENT);
        evt.list=this.list;
        document.dispatchEvent(evt);
    }
    static setStyles() {
        if(GoodsList.styles) return;
        GoodsList.styles=true;
        Utils.insertCss("body", {
            background: "#f5f5f5"
        })
        Utils.insertCss("body,div,p", {
            margin: "0px",
            padding: "0px"
        })
        Utils.insertCss(".goodsContainer", {
            width: "226px",
            height: "350px",
            margin: "10px 0px 0px 10px",
            background: "#fff",
            float: "left"
        })
        Utils.insertCss(".goodsInfo", {
            width:"220px",
            paddingLeft:"16px",
            cursor:"pointer",
            textDecoration:"none"
        })
        Utils.insertCss(".goodsImg", {
            width: "150px",
            height: "150px",
            margin: "20px 0px 0px 25px"
        })
        Utils.insertCss(".goodsImg:hover", {
            position:"relative",
            top:"-7px",
        })
        Utils.insertCss(".goodsTit", {
            fontSize: "14px",
            color: "#333333",
            margin: "0px 16px 10px",
            fontWeight: "bold",
            textAlign: "left",
            lineHeight: "20px",
            height: "20px",
            whiteSpace: "nowrap",
            textOverflow: "ellipsis",
            overflow: "hidden",
            display:"block"
        })
        Utils.insertCss(".goodsDesc", {
            margin: "0px 0px 10px 16px",
            fontSize: "14px",
            color: "#e01222",
            display:"block"
        })
        Utils.insertCss(".goodsPrice", {
            paddingLeft:"16px",
            paddingTop:"13px",
            borderTop: "1px solid #f3f3f3"
        })
        Utils.insertCss(".leftCon", {
            float: "left"
        })
        Utils.insertCss(".priceDesc", {
            padding: "0 8px",
            height: "16px",
            lineHeight: "16px",
            backgroundColor: "#e6e6e6",
            fontSize: "10px",
            color: "#999",
            borderRadius: "2px",
            position: "relative",
            marginBottom:"10px"
        })
        Utils.insertCss(".priceDesc:after", {
            content: "\".\"",
            position: "absolute",
            left: "0",
            right: "0",
            bottom: "-6px",
            margin: "0 auto",
            width: "0",
            height: "0",
            borderWidth: "3px",
            borderStyle: "solid dashed dashed",
            borderColor: "#e6e6e6 transparent transparent",
            pointerEvents: "none",
        })
        Utils.insertCss(".priceNow", {
            fontSize: "24px",
            color: "#e01222",
            marginRight: "2px",
            lineHeight: "1",
            minWidth: "50px",
            marginBottom:"3px"
        })
        Utils.insertCss(".priceNow span", {
            fontSize: "14px"
        })
        Utils.insertCss(".pricePre", {
            lineHeight: "1.2",
            color: "#999",
            fontSize: "18px",
        })
        Utils.insertCss(".rightCon", {
            float: "right"
        })
        Utils.insertCss(".sale", {
            height: "18px",
            fontSize: "12px",
            color: "#999999",
            textAlign: "right",
            paddingRight: "10px",
        })
        Utils.insertCss(".sale span", {
            fontSize: "18px",
            color: "#df0021"
        })
        Utils.insertCss(".saleBtn", {
            marginTop: "15px",
            color: "#fff",
            height: "38px",
            lineHeight: "38px",
            fontSize: "16px",
            display: "block",
            width: "90px",
            textAlign: "center",
            background: "#df0021",
            textDecoration:"none",
            cursor:"pointer"
        })
        Utils.insertCss(".clearfix::after", {
            content: "\".\"",
            display: "block",
            overflow: "hidden",
            visibility: "hidden",
            height: "0px",
            clear: "both"
        })
    }
}

Utils.js文件,是一个工具包文件:

export default class Utils{
    static createE(elem,style,prep){
        elem=document.createElement(elem);
        if(style) for(let prop in style) elem.style[prop]=style[prop];
        if(prep) for(let prop in prep) elem[prop]=prep[prop];
        return elem;
    }
    static appendTo(elem,parent){
        if (parent.constructor === String) parent = document.querySelector(parent);
        parent.appendChild(elem);
    }
    static insertBefore(elem,parent){
        if(parent.constructor === String) parent=document.querySelector(parent);
        parent.insertBefore(elem,parent.firstElementChild);
    }
    static randomNum(min,max){
        return Math.floor(Math.random*(max-min)+min);
    }
    static randomColor(alpha){
        alpha=alpha||Math.random().toFixed(1);
        if(isNaN(alpha)) alpha=1;
        if(alpha>1) alpha=1;
        if(alpha<0) alpha=0;
        let col="rgba(";
        for(let i=0;i<3;i++){
            col+=Utils.randomNum(0,256)+",";
        }
        col+=alpha+")";
        return col;
    }
    static insertCss(select,styles){
        if(document.styleSheets.length===0){
            let styleS=Utils.createE("style");
            Utils.appendTo(styleS,document.head);
        }
        let styleSheet=document.styleSheets[document.styleSheets.length-1];
        let str=select+"{";
        for(var prop in styles){
            str+=prop.replace(/[A-Z]/g,function(item){
                return "-"+item.toLocaleLowerCase();
            })+":"+styles[prop]+";";
        }
        str+="}"
        styleSheet.insertRule(str,styleSheet.cssRules.length);
    }
    static addClass(elem,className){
        let arr=(elem.className+" "+className).match(/\S+/g);
        arr=arr.filter((item,index)=>arr.indexOf(item,index+1)<0)
        elem.className=arr.join(" ");
    }
    static removeClass(elem,className){
        if(!elem.className) return;
        let arr=elem.className.match(/\S+/g);
        let arr1=className.match(/\S+/g);
        arr1.forEach(item=>{
            arr=arr.filter(t=>t!==item)
        })
        elem.className=arr.join(" ");
    }
    static hasClass(elem,className){
        if(!elem.className) return false;
        let arr=elem.className.match(/\S+/g);
        let arr1=className.match(/\S+/g);
        let res;
        arr1.forEach(item=>{
            res= arr.some(it=>it===item)
        })
        return res;
    }
    static loadImg({list,basePath,callback}){
        if(!list || list.length===0) return;
        if(basePath) list=list.map(item=>basePath+item);
        let img=Utils.createE("img");
        img.data={
            list:list,
            callback:callback,
            resultList:[],
            num:0
        }
        img.addEventListener("load",Utils.loadImgHandler);
        img.src=list[img.data.num];
    }
    static loadImgHandler(e){
        let data=e.currentTarget.data;
        data.resultList.push(e.currentTarget.cloneNode(false));
        data.num++;
        if(data.num>data.list.length-1){
            e.currentTarget.removeEventListener("load",Utils.loadImgHandler);
            data.callback(data.resultList);
            data=null;
            return;
        }
        e.currentTarget.src=data.list[data.num];
    }
}
原生js实现购物车添加删除商品、计算价格功能原生js实现购物车添加删除商品、计算价格功能 蒲公英芽 发布了66 篇原创文章 · 获赞 36 · 访问量 2万+ 私信 关注
上一篇:Java 有关 Integer 一个好玩的包装类


下一篇:Atcoder Regular Contest 128