计数器

功能需求
  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;
        },{})
    }
}
posted on 2020-07-28 20:17  94Lucky  阅读(230)  评论(0编辑  收藏  举报