使用原生javascript開發(fā)計算器實例代碼
計算器的主要作用是進行數(shù)字運算,開發(fā)一個計算器功能的web實例,有助于更好的掌握js基礎(chǔ)的數(shù)字運算能力。
本實例詳細分析一個js計算器的開發(fā)步驟,學習本教程時最好先具備一些基礎(chǔ)的js知識。
計算器包括顯示數(shù)字區(qū)域和按鍵區(qū)域兩大部分,先把計算器的這兩個區(qū)域的html元素編寫出來,如下所示:
<div class="calculator_wrap" id="calculator"><!--計算器外包元素--> <div class="show_num"><!--顯示數(shù)字區(qū)域--> <div class="num_save" id="numSave"></div><!--計算公式--> <div class="num_cur" id="numCur">0</div><!--計算結(jié)果--> <div class="show_m" id="showM">M</div><!--記憶存儲標志--> </div> <div class="btn_wrap" id="btnWrap"><!--按鈕區(qū)域--> <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><!--正負轉(zhuǎn)換--> <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> <!--倒數(shù)--> <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><!--小數(shù)點--> <div class="btn" data-key="Base" data-value="+">+</div><!--加--> </div> </div>
讀者可以自己編寫一些樣式,設(shè)計一個自己喜歡的計算器效果。本實例的計算器效果如下圖所示:

樣式代碼:
.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;}
對于新手來說,計算器功能看起來好像很復雜,那么多按鈕、多種計算方式,不知如何開始。其實任何一個功能,只需要理清楚思路,一步一步編寫代碼,會發(fā)現(xiàn)實現(xiàn)起來都不難。
1 獲取各個html元素
web前端不論要在頁面上做什么,都要先獲取頁面上的各個DOM元素??雌饋碚麄€計算器的按鈕較多,實際開發(fā)中可以使用事件代理來操作按鈕,所以只獲取所有按鈕的容器元素即可。代碼如下:
//獲取外包元素
var eCalculator = document.getElementById('calculator');
//保存運算數(shù)據(jù)(公式)容器
var eNumSave = document.getElementById('numSave');
//當前數(shù)字容器
var eNumCur = document.getElementById('numCur');
//按鈕外部容器,用于事件代理
var eBtnWrap = document.getElementById('btnWrap');
//記憶存儲標志元素
var eShowM = document.getElementById('showM');
2 聲明相關(guān)變量
在運算過程中,需要一些變量來進行輔助計算、存儲結(jié)果和判斷等,如下所示:
//運算公式 var sStep = ''; //當前數(shù)字 var sCurValue = '0'; //運算結(jié)果 var nResult = null; //運算符 var sMark = ''; //MR記憶存儲數(shù)據(jù) var nMvalue = 0; //輸入狀態(tài)。false:輸入數(shù)字替換原數(shù)字;true:輸入數(shù)字加到原數(shù)字后面; var bLogStatus = false;
3 按鍵上添加點擊事件
因為整個計算器按鍵較多,每一個按鈕都單獨綁定一個事件會顯得太多,很繁瑣,還會影響性能,且容易出錯。所以剛才只獲取了按鍵的外部容器 eCalculator。
再使用事件代理,就只需要在容器上添加點擊事件,判斷當前點擊的按鍵是哪一個,再執(zhí)行對應的計算即可。用鼠標點擊按鍵的時候,可能會因為點得太快而選擇了按鍵上的文字,因此還需要在外包容器上添加一個阻止默認行為的操作,代碼如下所示:
//外包容器添加鼠標按下事件,用于防止選中文字
eCalculator.addEventListener('mousedown',function(event){
//阻止鼠標按下時的默認行為,防止點擊按鈕過快時選中文字
event.preventDefault();
});
//按鍵容器添加點擊事件,用于代理所有按鍵的操作
eBtnWrap.addEventListener('click',function(event){
});
3.1 獲取點擊的按鍵和值
通過事件函數(shù)傳入的event參數(shù),可以獲取到鼠標點擊的元素。再通過元素上的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 判斷按鍵及值,數(shù)字鍵和小數(shù)點執(zhí)行輸入操作
如果按鍵屬性data-key是'Num'表示按下的是數(shù)字,'Point'表示小數(shù)點。
這些按鍵都是執(zhí)行輸入,因為數(shù)字有多個,所以把數(shù)字輸入封裝到fnInputNum函數(shù)中。再封裝fnShowResult函數(shù)把數(shù)據(jù)顯示到顯示數(shù)字區(qū)域。如下所示:
eBtnWrap.addEventListener('click',function(event){
/* … */
//判斷點擊的是否是按鍵
if(key){
//用switch語句判斷不同的按鍵執(zhí)行對應的操作
switch(key){
//數(shù)字鍵執(zhí)行操作
case 'Num':
fnInputNum(value);
break;
//小數(shù)點操作
case 'Point':
//判斷是否有已小數(shù)點,用于限制只能輸入一個小數(shù)點
if(sCurValue.indexOf('.')==-1){
sCurValue = sCurValue + '.';
bLogStatus = true;
}
break;
}
//顯示數(shù)據(jù)到顯示數(shù)字區(qū)域
fnShowResult();
}
});
//輸入數(shù)字
function fnInputNum(num){
//根據(jù)輸入狀態(tài)判斷是替換當前數(shù)字還是添加到當前數(shù)字后面
if(bLogStatus){
sCurValue = sCurValue + num;
}else{
//限制第一個數(shù)字不能是0
if(num!=0){
bLogStatus = true;
}
sCurValue = num;
}
}
//顯示計算結(jié)果
function fnShowResult(){
//顯示計算公式
eNumSave.innerHTML = sStep;
//限制數(shù)字總長度
if(sCurValue.length>14){
sCurValue = sCurValue.slice(0,14);
}
//顯示當前數(shù)字
eNumCur.innerHTML = sCurValue;
}
這時候已經(jīng)可以點擊數(shù)字和小數(shù)點,輸入到計算器顯示屏上,如圖所示:

3.3 加減乘除運算
計算器最基本的就是加減乘除運算。為了實現(xiàn)對數(shù)字進行加減乘除并計算結(jié)果功能,封裝fnCountResult、fnBaseCount和fnEqual三個函數(shù)。
fnCountResult用于根據(jù)運算符計算結(jié)果;
fnBaseCount修改計算公式或計算結(jié)果;
fnEqual用于按下=號時計算結(jié)果,并重置數(shù)據(jù)。如下所示:
eBtnWrap.addEventListener('click',function(event){
/* … */
//判斷點擊的是否是按鍵
if(key){
//用switch語句判斷不同的按鍵執(zhí)行對應的操作
switch(key){
/* … */
//加減乘除基本運算
case 'Base':
fnBaseCount(value);
break;
//等于
case 'Equal':
fnEqual();
break;
}
//顯示數(shù)據(jù)到顯示數(shù)字區(qū)域
fnShowResult();
}
});
//計算結(jié)果
function fnCountResult(){
//判斷當前運算符并執(zhí)行運算
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;
}
}
//加減乘除基礎(chǔ)運算
function fnBaseCount(key){
//如果是輸入狀態(tài),進行運算
if(bLogStatus){
//修改輸入狀態(tài)
bLogStatus = false;
//計算公式
sStep = sStep + ' ' + sCurValue + ' ' + key;
//計算結(jié)果
fnCountResult();
sCurValue = ''+nResult;
}else{
//如果公式為空,先加上原始數(shù)字
if(sStep==''){
sStep = sCurValue + ' ' + key;
}else{ //如果已有公式,更改最后的運算符
sStep = sStep.slice(0,sStep.length-1) + ' ' + key;
}
}
//更改運算符,用于計算
sMark = key;
}
//等于
function fnEqual(){
//如果沒有運算符,阻止后續(xù)操作
if(sMark=='')return;
//計算結(jié)果
fnCountResult();
sCurValue = ''+nResult;
//重置數(shù)據(jù)
sStep = '';
sMark = '';
bLogStatus = false;
}
現(xiàn)在已經(jīng)可以在計算器上做加減乘除的計算了,如圖所示:

3.4 再給其他按鍵添加操作,代碼如下所示:
eBtnWrap.addEventListener('click',function(event){
/* … */
//判斷點擊的是否是按鍵
if(key){
//用switch語句判斷不同的按鍵執(zhí)行對應的操作
switch(key){
/* … */
//清除
case 'Clear':
fnClear()
break;
//退格
case 'BACK':
fnBack();
break;
//CE
case 'CE':
//清空當前顯示數(shù)值
sCurValue = '0';
bLogStatus = false;
break;
//取反
case 'Negate':
//當前數(shù)值取反
sCurValue = ''+(-sCurValue);
break;
//取平方根
case 'Square':
//當前數(shù)值取平方根
nResult = Math.sqrt(+sCurValue);
//其他數(shù)據(jù)初始化
sCurValue = ''+nResult;
sStep = '';
sMark = '';
bLogStatus = false;
break;
//倒數(shù)
case 'Reciprocal':
//當前數(shù)值取倒數(shù)
//其他數(shù)據(jù)初始化
nResult = 1/sCurValue;
sCurValue = ''+nResult;
sStep = '';
sMark = '';
bLogStatus = false;
break;
//M系列
case 'MC':
//記憶數(shù)值清零
nMvalue = 0;
fnShowM()
break;
case 'MR':
//顯示記憶數(shù)值
sCurValue = '' + nMvalue;
fnShowM()
break;
case 'MS':
//記憶數(shù)值改為當前數(shù)值
nMvalue = +sCurValue;
fnShowM()
break;
case 'MA':
//當前數(shù)值加到記憶數(shù)值中
nMvalue += +sCurValue;
fnShowM()
break;
case 'ML':
//從記憶數(shù)值中減去當前數(shù)值
nMvalue -= +sCurValue;
fnShowM()
break;
}
//顯示數(shù)據(jù)到顯示數(shù)字區(qū)域
fnShowResult();
}
});
//清除
function fnClear(){
//初始化所有數(shù)據(jù)
sStep = '';
sCurValue = '0';
nResult = null;
sMark = '';
bLogStatus = false;
}
//退格
function fnBack(){
//必須是輸入狀態(tài)才可以退格
if(bLogStatus){
//減去數(shù)值最后一位數(shù)
sCurValue = sCurValue.slice(0,sCurValue.length-1);
//如果最后數(shù)值為空或負號(-),改為0,重置輸入狀態(tài)為false,不可再退格
if(sCurValue==''||sCurValue=='-'){
sCurValue = '0';
bLogStatus = false;
}
}
}
//判斷是否有M記憶存儲
function fnShowM(){
bLogStatus = false;
//判斷是否顯示記憶存儲標志
eShowM.style.display = nMvalue==0?'none':'block';
}
4 綁定鍵盤事件
寫到這里,計算器已經(jīng)可以正常使用了。不過只能用鼠標點擊按鍵操作效率不高,為了可以更快的使用計算器,還需要加上鍵盤事件,當按下對應按鍵時,執(zhí)行操作,如下所示:
//鍵盤事件
document.addEventListener('keyup',function(event){
//獲取當前鍵盤按鍵
var key = event.key;
//獲取按鍵code
var code = event.keyCode;
//限制正確的按鍵才修改顯示的數(shù)據(jù)
var comply = false;
//輸入數(shù)字
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){
//顯示數(shù)據(jù)到計算器屏幕
fnShowResult();
}
});
一個簡單的計算器就完成了,如果以學習為目的話,建議不要直接復制代碼,最好直接手動輸入代碼及注釋,加深印象和提高學習效果。
總結(jié)
到此這篇關(guān)于使用原生javascript開發(fā)計算器的文章就介紹到這了,更多相關(guān)原生js開發(fā)計算器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用ef6創(chuàng)建oracle數(shù)據(jù)庫的實體模型遇到的問題及解決方案
這篇文章主要介紹了使用ef6創(chuàng)建oracle數(shù)據(jù)庫的實體模型遇到的問題及解決方案,需要的朋友可以參考下2017-11-11
Javascript連接多個數(shù)組不用concat來解決
這篇文章主要介紹了不用concat解決Javascript連接多個數(shù)組,需要的朋友可以參考下2014-03-03
laydate只顯示時分 不顯示秒的功能實現(xiàn)方法
今天小編就為大家分享一篇laydate只顯示時分 不顯示秒的功能實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

