js的計數器元件開發
阿新 • • 發佈:2020-07-28
計數器
功能需求
- 左右兩端分別是"-"和"+", 紅色
- 中間數值預設是"1",最大值是99,最小值是1
- 大於等於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; },{}) } }