Native js realizes the functions of adding and deleting goods and calculating prices in shopping cart

Shopping Cart

Functional requirements:

  1. Create shopping cart content based on data;
  2. Realize the function of adding goods to shopping cart;
  3. Increase and decrease the number of goods in shopping cart;
  4. Realize the function of deleting goods in shopping cart;
  5. Shopping cart full selection function;
  6. Calculate the total number of pieces and total price at the bottom;

Take a look at the effect:


Analysis:

  • It is divided into three files: GoodsList.js, which is used to create commodity list; ShoppingCart.js, which is used to create shopping cart content, StepNumber.js, which is used to create components in shopping cart that operate commodity quantity.
  • To distinguish communication between pages.
  • In the case, the shopping cart data is shopCartArr, so any operation related to the data is better to be in the same file to ensure the data synchronization. No matter which file is used for operation, the data will be uniformly distributed to the Html file for operation.
  • Class can be instantiated. It is not recommended to add id attribute to the element in the class file, because when multiple classes are instantiated, multiple identical IDS will appear on the page, which violates the uniqueness of id attribute.
  • When setting properties for input, if the innerHTML method is used, some properties of input may not function, and DOM elements can be used for operation.

The code is attached below:

html file, simulate data, listen to the sending events of each file, and operate on the data:

<!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";
        //Listen to add product event
        document.addEventListener(ADD_GOODS_EVENT,addGoodsEvent);
        //Listening for deleting product events
        document.addEventListener(DELETE_EVENT,deleteEvent);
        //Events triggered by listening for changing the quantity of goods
        document.addEventListener(STEP_CHANGE_EVENT,stepChangeEvent);
        //Listen to the click multiple box event
        document.addEventListener(CHECKED_EVENT,checkedEvent);
        //Simulated product list data
        var arr=[
            {id:"0001",img:"img01.webp",title:"I don't know fire, ugly orange, ugly orange, 5 jin",desc:"Second pieces 9.9 element",price_desc:"1 Annual lowest price",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:"Mother's Feast (2.0-2.3 Two) 10",desc:"Catch up now",price_desc:"82 Lowest price in history",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:"Good taste 100%Pure cocoa butter dark chocolate",desc:"Buy one for free",price_desc:"181 Lowest price in history",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:"Buy one and get one for free g/box",desc:"12 pieces for free",price_desc:"1 Annual lowest price",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:"Wuchang organic rice fragrance 500 g(1 Jin)",desc:"Authentic Wuchang rice",price_desc:"138 Lowest price in history",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:"Hunan hairy fish and dried fish 20 bags of sugar and vinegar",desc:"2 20% off 3 pieces 70% off",price_desc:"230 Lowest price in history",price_now:"13.9",price_pre:"19.9",sale:"103",href:"https://item.jd.com/49202317748.html",weight:"0.15",state:"1"},
        ]
        //Cart list data
        var shopCartArr=[];
        //Create item list
        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);
        }
        //Add merchandise
        function addGoodsEvent(e){
            let arr=shopCartArr.filter(item=>item.id===e.list.id);
            if(arr.length===0){
                //If the product is added for the first time, do the following
                let data={
                    id:e.list.id,
                    //If the product is not available for sale, checked is set to 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,
                    //When state is 1, it means the goods are available for sale; when state is 0, it means they are not available for sale
                    state:e.list.state,
                    subPrice:Number(e.list.price_now).toFixed(2),
                    href:"https://item.jd.com/21562085787.html"
                }
                shopCartArr.push(data);
            }else{
                //If the item is not added for the first time, change the quantity of the item
                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);
            }
            //Retrieve cart data
            setshoppingCart();
        }
        function deleteEvent(e){
            //Delete merchandise
            shopCartArr=shopCartArr.filter(item=>item.id!==e.data.id);
            //Retrieve cart data
            setshoppingCart();
        }
        function stepChangeEvent(e){
            //Change quantity, subtotal and weight of goods
            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);
                }
            })
            //Retrieve cart data
            setshoppingCart();
        }
        function checkedEvent(e){
            if(e.data==="all"){
                //If you click the select all button
                shopCartArr.forEach(item=>{
                    //Change the checkbox status in front of the saleable products
                    if(item.state==1) item.checked=e.tag.checked;
                })
            }else{
                //If you click the checkbox of a product, only change its checked value
                shopCartArr.forEach(item=>{
                    if(item.id===e.data.id) item.checked=e.tag.checked;
                })
            }
            //Retrieve cart data
            setshoppingCart();
        }

        var shoppingCart;
        //Create cart content
        function setshoppingCart(){
            if(shoppingCart){
                //Delete the contents of the previous shopping cart and recreate it
                shoppingCart.elem.remove();
                shoppingCart.elem=null;
            }
            shoppingCart=new ShoppingCart(shopCartArr);
            shoppingCart.appendTo("body");
        }
    </script>
</body>
</html>

ShoppingCart.js file, create shopping cart content, and send events when the shopping cart DOM element is operated:

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;
        //Create outer container
        let div=Utils.createE("div");
        div.className="cart_main";
        //Create header content
        let cartTh=Utils.createE("div",{},{
            className:"cart_table_th"
        })
        this.createCartTableTh(cartTh);
        Utils.appendTo(cartTh,div);
        //Create cart body content
        let cartCont=Utils.createE("div",{},{
            className:"cart_content"
        })
        this.createShoppingCartCont(cartCont);
        Utils.appendTo(cartCont,div);
        //Create bottom total
        let cartBottom=Utils.createE("div",{},{
            className:"cart_bottom"
        })
        this.createCartBottom(cartBottom);
        Utils.appendTo(cartBottom,div);
        //Insert style
        ShoppingCart.setStyle();
        //Calculate the total displayed
        this.totalCount();
        return div;
    }
    appendTo(parent){
        Utils.appendTo(this.elem,parent);
    }
    createCartTableTh(parent){
        //Create header content
        let str=`<div class="th th_chk"><label class="cart_checkbox"><span>All election<span></label></div>
        <div class="th th_item">Commodity information</div>
        <div class="th th_price">Amount of money</div>
        <div class="th th_amount">Number</div>
        <div class="th th_weight">weight</div>
        <div class="th th_location">&nbsp;</div>
        <div class="th th_sum">Subtotal</div>
        <div class="th th_op">operation</div>`;
        parent.innerHTML=str;
        let input=Utils.createE("input",{},{
            type:"checkbox",
            //The default value of the check box is set according to the product with state 1
            checked:this.list.filter(item=>item.state==1).every(item=>item.checked)
        })
        //Listen to click events for multiple check boxes
        input.addEventListener("click",e=>this.checkboxClickHandler(e,"all"));
        Utils.insertBefore(input,parent.firstElementChild.firstElementChild);
    }
    createShoppingCartCont(parent){
        //Create cart body content
        this.list.forEach(item => {
            let ul=Utils.createE("ul",{
                //If the item is not available for sale, add a gray background
                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?"In stock":"No goods"}</li>
            <li class="td_sum">${item.subPrice}</li>
            <li class="td_op">delete</li>`;
            let input=Utils.createE("input",{},{
                type:"checkbox",
                checked:item.checked,
                //If the product is not available for sale, set the multi selection box to be non clickable
                disabled:item.state==0?true:false
            });
            Utils.appendTo(input,ul.firstElementChild);
            //Create step
            let step=this.createStepNumber(item);
            Utils.appendTo(step,ul.firstElementChild.nextElementSibling.nextElementSibling.nextElementSibling);
            //Listen for delete events
            ul.lastElementChild.addEventListener("click",()=>this.deleGoodsInfo(item));
            Utils.appendTo(ul,parent);
            //Listen to click events for multiple boxes of sellable goods
            if(item.state==1) input.addEventListener("click",e=>this.checkboxClickHandler(e,item));
        });
    }
    createStepNumber(obj){
        let stepNumber=new StepNumber(obj);
        return stepNumber.elem;
    }
    createCartBottom(parent){
        //Create bottom content
        let label=Utils.createE("label");
        let input=Utils.createE("input",{},{
            type:"checkbox",
            //The default value of the check box is set according to the product with state 1
            checked:this.list.filter(item=>item.state==1).every(item=>item.checked)
        })
        //Select all to listen to click events
        input.addEventListener("click",e=>this.checkboxClickHandler(e,"all"));
        Utils.appendTo(input,label);
        Utils.appendTo(Utils.createE("span",{margin:"0px"},{textContent:"All election"}),label);
        Utils.appendTo(label,parent);
        //Create delete button
        let delBtn=Utils.createE("a",{},{
            className:"cart_bottom_del",
            textContent:"delete"
        });
        //Listen for delete events
        delBtn.addEventListener("click",()=>this.deleGoodsInfo("all"));
        Utils.appendTo(delBtn,parent);
        //Create text content
        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(){
        //Total, initially set to 0
        this.totalPrices=0;
        this.totalWeight=0;
        this.totalNum=0;
        this.list.forEach(item=>{
            if(item.checked){
                //Calculate the total for the selected item
                this.totalPrices+=Number(item.subPrice);
                this.totalWeight+=Number(item.subWeight);
                this.totalNum+=Number(item.num);
            }
        })
        this.spanPrice.innerHTML=`Total commodity price<em>¥${this.totalPrices.toFixed(2)}</em>`;
        this.spanWeight.innerHTML=`Total weight of goods:${this.totalWeight.toFixed(2)}kg`;
        this.spanNum.innerHTML=`In total:${this.totalNum}Commodity`;
    }
    checkboxClickHandler(e,type){
        //Multiple selection box throwing event
        let evt=new Event(ShoppingCart.CHECKED_EVENT);
        evt.data=type;
        evt.tag=e.target;
        document.dispatchEvent(evt);
    }
    deleGoodsInfo(type){
        //Delete merchandise
        if(type==="all"){
            this.list.forEach(item=>{
                //Using recursive loops
                if(item.checked) this.deleGoodsInfo(item);
            })
        }else{
            //Delete goods distribution event
            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 file, click the left and right buttons to change the quantity:

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;
        //Create outer container
        let div=Utils.createE("div");
        div.className="item_amount clearfix";
        //Left button
        let reduceBtn=Utils.createE("a",{},{
            className:"btn_reduce",
            textContent:"-"
        })
        //Input box
        let input=Utils.createE("input",{},{
            className:"amount_inp",
            type:"text",
            value:this.num,
            //If state is 0, set input not to be inputted
            disabled:this.data.state==1?false:true
        })
        //Right button
        let addBtn=Utils.createE("a",{},{
            className:"btn_add",
            textContent:"+"
        })
        Utils.appendTo(reduceBtn,div);
        Utils.appendTo(input,div);
        Utils.appendTo(addBtn,div);
        //Set style
        StepNumber.setStyles();
        //Monitor click events for products with 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;
        //If the clicked element is not a or input, directly jump out
        if(target.nodeName!=="A"&&target.nodeName!=="INPUT") return;
        if(Utils.hasClass(target,"btn_reduce")){
            //Click the button on the left
            this.num--;
            this.setStep(target.nextElementSibling);
        }else if(Utils.hasClass(target,"btn_add")){
            //Click the button on the right
            this.num++;
            this.setStep(target.previousElementSibling);
        }else if(target.nodeName==="INPUT"){
            //Click input to listen for input events
            target.addEventListener("input",e=>this.inputHandler(e));
        }
    }
    inputHandler(e){
        //Use throttling to improve efficiency
        if(this.ids) return;
        this.ids=setTimeout(()=>{
            clearTimeout(this.ids);
            this.ids=0;
            this.setInputsValue(e.target);
        },500);
    }
    setInputsValue(target){
        let value=target.value;
        //Disable non numeric input
        value=value.replace(/\D/g,"");
        //If the value of input is null, make it equal to 1
        if(value.length===0) value="1";
        this.num=value;
        this.setStep(target);
    }
    setStep(obj){
        //Set value
        if(this.num<=1) this.num=1;
        if(this.num>=999) this.num=999;
        obj.value=this.num;
        //Throwing incident
        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 file to create a product list:

import Utils from './Utils.js';
export default class GoodsList {
    static styles=false;
    static ADD_GOODS_EVENT="add_goods_event";
    constructor(_list, basePath) {
        //The path of splicing pictures
        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";
        //Page structure
        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">Already sold<span>${_list.sale}</span>piece</p></div></div>`;
        let a=Utils.createE("a",{},{
            className:"saleBtn",
            textContent:"add to cart"
        })
        //Listen to add product event
        a.addEventListener("click",e=>this.addShoppingCartHandler(e))
        Utils.appendTo(a,div.lastElementChild.lastElementChild)
        //Writing style
        GoodsList.setStyles();
        return div;
    }
    appendTo(parent) {
        Utils.appendTo(this.elem, parent);
    }
    addShoppingCartHandler(e){
        //Throwing incident
        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 is a toolkit file:

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];
    }
}
66 original articles published, 36 praised, 20000 visitors+
Private letter follow

Tags: Attribute

Posted on Wed, 05 Feb 2020 10:13:20 -0500 by regexpert