計算器的主要做用是進行數字運算,開發一個計算器功能的web實例,有助於更好的掌握js基礎的數字運算能力。html
本實例詳細分析一個js計算器的開發步驟,學習本教程時最好先具有一些基礎的js知識。前端
計算器包括顯示數字區域和按鍵區域兩大部分,先把計算器的這兩個區域的html元素編寫出來,以下所示:web
<div class="calculator_wrap" id="calculator"><!--計算器外包元素--> <div class="show_num"><!--顯示數字區域--> <div class="num_save" id="numSave"></div><!--計算公式--> <div class="num_cur" id="numCur">0</div><!--計算結果--> <div class="show_m" id="showM">M</div><!--記憶存儲標誌--> </div> <div class="btn_wrap" id="btnWrap"><!--按鈕區域--> <div class="btn" data-key="MC">MC</div><!--記憶清零--> <div class="btn" data-key="MR">MR</div><!--記憶讀取--> <div class="btn" data-key="MS">MS</div><!--存儲記憶--> <div class="btn" data-key="MA">M+</div><!--記憶加--> <div class="btn" data-key="ML">M-</div><!--記憶減--> <div class="btn" data-key="BACK">←</div><!--退格--> <div class="btn" data-key="CE">CE</div><!--清除當前--> <div class="btn" data-key="Clear">C</div><!--清除--> <div class="btn" data-key="Negate">±</div><!--正負轉換--> <div class="btn" data-key="Square">√ ̄</div><!--平方根--> <div class="btn" data-key="Num" data-value="7">7</div><!--7--> <div class="btn" data-key="Num" data-value="8">8</div><!--8--> <div class="btn" data-key="Num" data-value="9">9</div><!--9--> <div class="btn" data-key="Base" data-value="/">/</div><!--除--> <div class="btn" data-key="Percentage">%</div><!--百分號--> <div class="btn" data-key="Num" data-value="4">4</div><!--4--> <div class="btn" data-key="Num" data-value="5">5</div><!--5--> <div class="btn" data-key="Num" data-value="6">6</div><!--6--> <div class="btn" data-key="Base" data-value="*">*</div><!--乘--> <div class="btn" data-key="Reciprocal">1/x</div> <!--倒數--> <div class="btn" data-key="Num" data-value="1">1</div><!--1--> <div class="btn" data-key="Num" data-value="2">2</div><!--2--> <div class="btn" data-key="Num" data-value="3">3</div><!--3--> <div class="btn" data-key="Base" data-value="-">-</div><!--減--> <div class="btn equal" data-key="Equal">=</div><!--等於--> <div class="btn zero" data-key="Num" data-value="0">0</div><!--0--> <div class="btn" data-key="Point">.</div><!--小數點--> <div class="btn" data-key="Base" data-value="+">+</div><!--加--> </div> </div>
讀者能夠本身編寫一些樣式,設計一個本身喜歡的計算器效果。本實例的計算器效果以下圖所示:函數
樣式代碼:性能
.calculator_wrap{width:240px;height:360px;padding:10px;margin:30px auto;border:1px solid #8acceb;background:#d1f1ff;} .calculator_wrap .show_num{position:relative;padding:0 8px;height:60px;background:#fff;text-align:right;} .calculator_wrap .show_m{position: absolute;left:10px;bottom:3px;display:none;} .calculator_wrap .num_save{height:26px;line-height:26px;font-size:12px;white-space:nowrap;} .calculator_wrap .num_cur{font-size:28px;height:34px;line-height:34px;} .calculator_wrap .btn_wrap{font-size:0px;} .calculator_wrap .btn{display:inline-block;width:38px;height:38px;line-height:38px;text-align:center;border:1px solid #ccc;background:#666;color:#fff;font-size:14px;margin:10px 10px 0 0;cursor:pointer;} .calculator_wrap .btn:hover{background:#333;} .calculator_wrap .btn:nth-child(5n){margin-right:0px;} .calculator_wrap .equal{position:absolute;height:90px;line-height:90px;} .calculator_wrap .zero{width:90px;}
對於新手來講,計算器功能看起來好像很複雜,那麼多按鈕、多種計算方式,不知如何開始。其實任何一個功能,只須要理清楚思路,一步一步編寫代碼,會發現實現起來都不難。學習
1 獲取各個html元素spa
web前端不論要在頁面上作什麼,都要先獲取頁面上的各個DOM元素。看起來整個計算器的按鈕較多,實際開發中可使用事件代理來操做按鈕,因此只獲取全部按鈕的容器元素便可。代碼以下:設計
//獲取外包元素 var eCalculator = document.getElementById('calculator'); //保存運算數據(公式)容器 var eNumSave = document.getElementById('numSave'); //當前數字容器 var eNumCur = document.getElementById('numCur'); //按鈕外部容器,用於事件代理 var eBtnWrap = document.getElementById('btnWrap'); //記憶存儲標誌元素 var eShowM = document.getElementById('showM');
2 聲明相關變量3d
在運算過程當中,須要一些變量來進行輔助計算、存儲結果和判斷等,以下所示:代理
//運算公式 var sStep = ''; //當前數字 var sCurValue = '0'; //運算結果 var nResult = null; //運算符 var sMark = ''; //MR記憶存儲數據 var nMvalue = 0; //輸入狀態。false:輸入數字替換原數字;true:輸入數字加到原數字後面; var bLogStatus = false;
3 按鍵上添加點擊事件
由於整個計算器按鍵較多,每個按鈕都單獨綁定一個事件會顯得太多,很繁瑣,還會影響性能,且容易出錯。因此剛纔只獲取了按鍵的外部容器 eCalculator。
再使用事件代理,就只須要在容器上添加點擊事件,判斷當前點擊的按鍵是哪個,再執行對應的計算便可。用鼠標點擊按鍵的時候,可能會由於點得太快而選擇了按鍵上的文字,所以還須要在外包容器上添加一個阻止默認行爲的操做,代碼以下所示:
//外包容器添加鼠標按下事件,用於防止選中文字 eCalculator.addEventListener('mousedown',function(event){ //阻止鼠標按下時的默認行爲,防止點擊按鈕過快時選中文字 event.preventDefault(); }); //按鍵容器添加點擊事件,用於代理全部按鍵的操做 eBtnWrap.addEventListener('click',function(event){ });
3.1 獲取點擊的按鍵和值
經過事件函數傳入的event參數,能夠獲取到鼠標點擊的元素。再經過元素上的data-key和data-value屬性判斷鼠標點擊的是哪個按鍵以及它的值,以下所示:
eBtnWrap.addEventListener('click',function(event){ //獲取點擊的元素 var eTarget = event.target; //判斷按下的鍵 var key = eTarget.dataset.key; //獲取按下的值 var value = eTarget.dataset.value; });
3.2 判斷按鍵及值,數字鍵和小數點執行輸入操做
若是按鍵屬性data-key是'Num'表示按下的是數字,'Point'表示小數點。
這些按鍵都是執行輸入,由於數字有多個,因此把數字輸入封裝到fnInputNum函數中。再封裝fnShowResult函數把數據顯示到顯示數字區域。以下所示:
eBtnWrap.addEventListener('click',function(event){ /* … */ //判斷點擊的是不是按鍵 if(key){ //用switch語句判斷不一樣的按鍵執行對應的操做 switch(key){ //數字鍵執行操做 case 'Num': fnInputNum(value); break; //小數點操做 case 'Point': //判斷是否有已小數點,用於限制只能輸入一個小數點 if(sCurValue.indexOf('.')==-1){ sCurValue = sCurValue + '.'; bLogStatus = true; } break; } //顯示數據到顯示數字區域 fnShowResult(); } }); //輸入數字 function fnInputNum(num){ //根據輸入狀態判斷是替換當前數字仍是添加到當前數字後面 if(bLogStatus){ sCurValue = sCurValue + num; }else{ //限制第一個數字不能是0 if(num!=0){ bLogStatus = true; } sCurValue = num; } } //顯示計算結果 function fnShowResult(){ //顯示計算公式 eNumSave.innerHTML = sStep; //限制數字總長度 if(sCurValue.length>14){ sCurValue = sCurValue.slice(0,14); } //顯示當前數字 eNumCur.innerHTML = sCurValue; }
這時候已經能夠點擊數字和小數點,輸入到計算器顯示屏上,如圖所示:
3.3 加減乘除運算
計算器最基本的就是加減乘除運算。爲了實現對數字進行加減乘除並計算結果功能,封裝fnCountResult、fnBaseCount和fnEqual三個函數。
fnCountResult用於根據運算符計算結果;
fnBaseCount修改計算公式或計算結果;
fnEqual用於按下=號時計算結果,並重置數據。以下所示:
eBtnWrap.addEventListener('click',function(event){ /* … */ //判斷點擊的是不是按鍵 if(key){ //用switch語句判斷不一樣的按鍵執行對應的操做 switch(key){ /* … */ //加減乘除基本運算 case 'Base': fnBaseCount(value); break; //等於 case 'Equal': fnEqual(); break; } //顯示數據到顯示數字區域 fnShowResult(); } }); //計算結果 function fnCountResult(){ //判斷當前運算符並執行運算 switch(sMark){ case '+': nResult = nResult===null?+sCurValue:nResult + (+sCurValue); break; case '-': nResult = nResult===null?+sCurValue:nResult - sCurValue; break; case '*': nResult = nResult===null?+sCurValue:nResult * sCurValue; break; case '/': nResult = nResult===null?+sCurValue:nResult / sCurValue; break; default: nResult = +sCurValue; } } //加減乘除基礎運算 function fnBaseCount(key){ //若是是輸入狀態,進行運算 if(bLogStatus){ //修改輸入狀態 bLogStatus = false; //計算公式 sStep = sStep + ' ' + sCurValue + ' ' + key; //計算結果 fnCountResult(); sCurValue = ''+nResult; }else{ //若是公式爲空,先加上原始數字 if(sStep==''){ sStep = sCurValue + ' ' + key; }else{ //若是已有公式,更改最後的運算符 sStep = sStep.slice(0,sStep.length-1) + ' ' + key; } } //更改運算符,用於計算 sMark = key; } //等於 function fnEqual(){ //若是沒有運算符,阻止後續操做 if(sMark=='')return; //計算結果 fnCountResult(); sCurValue = ''+nResult; //重置數據 sStep = ''; sMark = ''; bLogStatus = false; }
如今已經能夠在計算器上作加減乘除的計算了,如圖所示:
3.4 再給其餘按鍵添加操做,代碼以下所示:
eBtnWrap.addEventListener('click',function(event){ /* … */ //判斷點擊的是不是按鍵 if(key){ //用switch語句判斷不一樣的按鍵執行對應的操做 switch(key){ /* … */ //清除 case 'Clear': fnClear() break; //退格 case 'BACK': fnBack(); break; //CE case 'CE': //清空當前顯示數值 sCurValue = '0'; bLogStatus = false; break; //取反 case 'Negate': //當前數值取反 sCurValue = ''+(-sCurValue); break; //取平方根 case 'Square': //當前數值取平方根 nResult = Math.sqrt(+sCurValue); //其餘數據初始化 sCurValue = ''+nResult; sStep = ''; sMark = ''; bLogStatus = false; break; //倒數 case 'Reciprocal': //當前數值取倒數 //其餘數據初始化 nResult = 1/sCurValue; sCurValue = ''+nResult; sStep = ''; sMark = ''; bLogStatus = false; break; //M系列 case 'MC': //記憶數值清零 nMvalue = 0; fnShowM() break; case 'MR': //顯示記憶數值 sCurValue = '' + nMvalue; fnShowM() break; case 'MS': //記憶數值改成當前數值 nMvalue = +sCurValue; fnShowM() break; case 'MA': //當前數值加到記憶數值中 nMvalue += +sCurValue; fnShowM() break; case 'ML': //從記憶數值中減去當前數值 nMvalue -= +sCurValue; fnShowM() break; } //顯示數據到顯示數字區域 fnShowResult(); } }); //清除 function fnClear(){ //初始化全部數據 sStep = ''; sCurValue = '0'; nResult = null; sMark = ''; bLogStatus = false; } //退格 function fnBack(){ //必須是輸入狀態才能夠退格 if(bLogStatus){ //減去數值最後一位數 sCurValue = sCurValue.slice(0,sCurValue.length-1); //若是最後數值爲空或負號(-),改成0,重置輸入狀態爲false,不可再退格 if(sCurValue==''||sCurValue=='-'){ sCurValue = '0'; bLogStatus = false; } } } //判斷是否有M記憶存儲 function fnShowM(){ bLogStatus = false; //判斷是否顯示記憶存儲標誌 eShowM.style.display = nMvalue==0?'none':'block'; }
4 綁定鍵盤事件
寫到這裏,計算器已經能夠正常使用了。不過只能用鼠標點擊按鍵操做效率不高,爲了能夠更快的使用計算器,還須要加上鍵盤事件,當按下對應按鍵時,執行操做,以下所示:
//鍵盤事件 document.addEventListener('keyup',function(event){ //獲取當前鍵盤按鍵 var key = event.key; //獲取按鍵code var code = event.keyCode; //限制正確的按鍵才修改顯示的數據 var comply = false; //輸入數字 if((code>=48&&code<=57)||(code>=96&&code<=105)){ fnInputNum(key); comply = true; } //加減乘除 if( key=='*'||key=='+'||key=='/'||key=='-'){ fnBaseCount(key); comply = true; } //esc鍵 if(code==27){ fnClear(); comply = true; } //回車鍵 if(code==13){ fnEqual(); comply = true; } //退格鍵 if(code==8){ fnBack(); comply = true; } if(comply){ //顯示數據到計算器屏幕 fnShowResult(); } });
一個簡單的計算器就完成了,若是以學習爲目的話,建議不要直接複製代碼,最好直接手動輸入代碼及註釋,加深印象和提升學習效果。