1. 程式人生 > 實用技巧 >js的計數器元件開發

js的計數器元件開發

計數器

功能需求
  1. 左右兩端分別是"-"和"+", 紅色
  2. 中間數值預設是"1",最大值是99,最小值是1
  3. 大於等於99後,右邊變為灰色,左邊是紅色,小於等於1後,相反

效果圖:
預設狀態:

99之後:

1以下:

中間:

分析:

  • 這個demo包括左右兩邊按鈕和中間文字框三個部分
  • 文字框要考慮輸入非數值的情況
  • 文字框數值達到上下限,要考慮左右兩邊的按鈕的停止點選和繼續點選,繼而優化效能。

下面附上程式碼

html頁面引入js檔案,例項化元件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module">
        import StepNumber from "./js/StepNumber.js";

        let step=new StepNumber();
        step.appendTo("body");
    </script>
</body>
</html>

StepNumber.js 檔案封裝元件

import Utils from "./Utils.js";

export default class StepNumber extends EventTarget{
    leftBn;
    rightBn;
    input;
    step=1;   //初始值
    ids;  //節流
    constructor(){
        super();
        this.elem=this.createElem();
    }
    createElem(){
        if(this.elem) return this.elem;
        let div=Utils.ce("div",{
            width:"80px",
            height:"22px",
            position:"relative"
        });
        this.leftBn=Utils.ce("a",{
            width:"15px",
            height:"20px",
            border:"1px solid #cccccc",
            display:"block",
            textDecoration: "none",
            color:"#ff0000",
            textAlign:"center",
            lineHeight:"20px",
            float:"left",
        })
        this.leftBn.href="javascript:void(0)";
        this.leftBn.textContent="-";
        this.input=Utils.ce("input",{
            border:"none",
            borderTop:"1px solid #cccccc",
            borderBottom:"1px solid #cccccc",
            textAlign:"center",
            outline:"none",
            float:"left",
            width:'42px',
            height:"18px"
        })
        this.input.value="1";
        this.rightBn=this.leftBn.cloneNode(false);
        this.rightBn.textContent="+";
        div.appendChild(this.leftBn);
        div.appendChild(this.input);
        div.appendChild(this.rightBn);
        this.input.addEventListener("input",e=>this.inputHandler(e));
        this.leftBn.addEventListener("click",e=>this.clickHandler(e));
        this.rightBn.addEventListener("click",e=>this.clickHandler(e));
        return div;
    }
    appendTo(parent){
        if (typeof parent === "string") parent = document.querySelector(parent);
        parent.appendChild(this.elem);
    }
    inputHandler(e){
        if(this.ids!==undefined) return   //input事件新增節流 
        this.ids=setTimeout(()=>{
            clearTimeout(this.ids);
            this.ids=undefined;
            this.setStep(this.input.value);
        },500)
    }
    clickHandler(e){
        var bn=e.currentTarget;
        if(bn.bool)return;       //防止浪費記憶體
        if(bn===this.leftBn){
            this.step--;
        }else{
            this.step++;
        }
        this.setStep(this.step);
    }
    setStep(_step){
        if(typeof _step==="string"){
            _step=Number(_step.replace(/\D/g,""));
        }
        if(_step>=99){
            _step=99;
            this.rightBn.style.color="#CCCCCC";
            this.rightBn.bool=true;
            this.leftBn.bool=false;
            this.leftBn.style.color="#ff0000"
        }else if(_step<=1){
            this.leftBn.style.color="#CCCCCC";
            this.leftBn.bool=true;
            this.rightBn.bool=false;
            this.rightBn.style.color="#ff0000"
            _step=1;
        }                          //中間數值不用設定,對應bool值為undefined,可以執行點選事件
        this.step=_step;
        this.input.value=this.step;
    }
}

Utils.js是一個工具包 ,只展示需要的部分了

export default class Utils{
   static time=0;
   static ids=0;
   static timeManage={};
   //程式碼執行時間
   static timeStart(){
        if(Utils.time) return;
        Utils.time=new Date().getTime();
    }
   static timeEnd(){
        var t=new Date().getTime()-Utils.time;
        Utils.time=0;
        return t;
    }
    static ts(){
        Utils.ids++;
        Utils.timeManage[Utils.ids]=new Date().getTime();
        return ids;
    }
    static te(id){
        if(!Utils.timeManage[Utils.id]) return 0;
        var t=new Date().getTime()-Utils.timeManage[Utils.id];
        delete Utils.timeManage[Utils.id];
        return t;
    }
    //隨機顏色
    static randomColor(){
        var col="#";
        for(var i=0;i<6;i++){
            col+=Math.floor(Math.random()*16).toString(16);
        }
        return col;
    }
    //隨機數值
    static random(min,max){
        return Math.floor(Math.random()*(max-min)+min);
    }
    //建立元素  設定樣式  插入父級元素
     static ce(type,style,parent){
        var elem=document.createElement(type);
        if(style){
            for(var prop in style){
                elem.style[prop]=style[prop];
            }
        }
        if(typeof parent==="string") parent=document.querySelector(parent);
        if(parent) parent.appendChild(elem);
        return elem;
    }
    //讀取css樣式
    static setStyle(styles){
        var style=document.createElement("style");
        document.head.appendChild(style);
        var styleSheet=document.styleSheets[document.styleSheets.length-1];
        for(var prop in styles){
            Utils.addCss(styleSheet,prop,styles[prop]);
        }
    }
    //新增css樣式
    static addCss(styleSheet,selector,style){
        var str=selector+" {";
        for(var prop in style){
            var value=style[prop]
            prop=prop.replace(/([A-Z])/g,function($1){
                return "-"+$1.toLowerCase();
            })
            str+=prop+":"+value+";"
        }
        str+=" }";
        styleSheet.insertRule(str,styleSheet.cssRules.length);
    }
    //css樣式轉化為js內樣式
    static CSStoString(str){
       return str.replace(/(?<=:)(.*?)(?=;)|-[a-z](?=.+:)|;/g,function(item){
            if(item===";") return ","
            if(item[0]==="-")  return item[1].toUpperCase();
            return "'"+item.trim()+"'";
        });
    }
    //字串css轉換為js內樣式
    static CSStoObject(str){
        str=Utils.CSStoString(str);
       return  str.split(",").reduce((value,item)=>{
           item=item.replace(/\n/g,"");
            var arr=item.split(":");
            arr[0]=arr[0].replace(/\s/g,"");
            if(arr[1]===undefined) return value;
            arr[1]=arr[1].replace(/'/g,"");
            value[arr[0]]=arr[1];
            return value;
        },{})
    }
}