日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

JS 实现计算器详解及实例代码(一)

發(fā)布時(shí)間:2023/12/15 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 JS 实现计算器详解及实例代码(一) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Javascript 實(shí)現(xiàn)計(jì)算器:

系列文章:

JS 實(shí)現(xiàn)計(jì)算器詳解及實(shí)例代碼(一)

Javascript 實(shí)現(xiàn)計(jì)算器時(shí)間功能詳解及實(shí)例(二)

小型JavaScript計(jì)算器

自己尋思出的解決方案,比較笨拙的方法,雖然完成了但是還有不少bug,用的方法也不是最有效的,基本功能算是完成了,一些小的細(xì)節(jié)地方也考慮到了,但是還有其他的細(xì)節(jié)需要處理。

總體設(shè)計(jì)思路是,先畫草圖 -> 設(shè)計(jì)UI -> 編寫UI代碼 -> 編寫CSS -> 編寫JS邏輯代碼;

面板(main-board)

面板整體尺寸設(shè)計(jì)

標(biāo)題欄(board-title)

字體: font: 30px/50px “Comic Sans MS”, “微軟雅黑”;

寬高:(100%, 50px);

屏顯區(qū)(board-result)

數(shù)字顯示區(qū)(result-up):

表達(dá)式顯示區(qū)(result-down):

按鈕區(qū)(board-keys),使用表格完成,然后給每個(gè)td添加onclick事件

完成界面

導(dǎo)入新字體

// main.css
@font-face {
font-family: Lovelo-Black;/×定義font的名字×/
src: url('font/Lovelo Black.otf');/*把下載的字體文件引入進(jìn)來×/
}

登錄后復(fù)制

代碼分析

代碼組織結(jié)構(gòu)

計(jì)算器對(duì)象:Calculator;

計(jì)算器屬性:

bdResult: 計(jì)算器面板上的屏顯區(qū)DOM對(duì)象;

operator:操作符數(shù)組,包括'+,-,×,÷,=';

digits:有效數(shù)字字符,包括'0-9'和點(diǎn)'.';

dot, equal, zero:'.', ‘=', ‘0'對(duì)應(yīng)三個(gè)字符,點(diǎn),等號(hào),字符'0';

digit:屏顯區(qū)上層的顯示的當(dāng)前輸入的數(shù)字;

expression:屏顯區(qū)下層的顯示的輸入的數(shù)字和操作符組成的表達(dá)式;

resSpan:屏顯區(qū)上層的顯示當(dāng)前數(shù)字的span對(duì)象;

resDown:屏顯區(qū)下層的顯示表達(dá)式的div對(duì)象;

last:上一次輸入的按鈕內(nèi)容;

allDigits:用表達(dá)式解析出來的表達(dá)式中所有的有效數(shù)字;

ops:用表達(dá)式字符串解析出來的表達(dá)式中所有的操作符;

hasEqual:判斷是否按了'='等號(hào)的標(biāo)識(shí)符;

lastRes:上一次計(jì)算出來的結(jié)果[TODO],尚未用到,待實(shí)現(xiàn)可以連續(xù)計(jì)算;

計(jì)算器方法:

init:計(jì)算器初始化方法;

addTdClick:給每個(gè)td即計(jì)算器按鈕添加點(diǎn)擊事件;

calculatorClickEvent:點(diǎn)擊事件;

btnClickHanlder:點(diǎn)擊事件處理函數(shù);

showCurrRes:處理屏顯區(qū)上層和下層將要顯示的內(nèi)容;

showText:將通過showCurrRes處理的結(jié)果顯示出來;

addZero:對(duì)表達(dá)式前面加'0'操作;

calResult:計(jì)算結(jié)果;

clearData:清空數(shù)據(jù);

hasOperator:判斷表達(dá)式中是否有操作符;

isOperator:判斷當(dāng)前字符是否是操作符;

delHeadZero:刪除表達(dá)式開頭的'0';

輔助方法

getResSpan:獲取屏顯上層的span對(duì)象;

$tag:根據(jù)標(biāo)簽名去獲取標(biāo)簽對(duì)象;

$:根據(jù)id去獲取DOM對(duì)象;

代碼邏輯

使用方法

引入Calculator.js文件(在編寫完UI的基礎(chǔ)上)

創(chuàng)建對(duì)象并初始化:new Calculator().init();

計(jì)算器對(duì)象

// 計(jì)算器對(duì)象
function Calculator() {
 
 // 私有屬性
 this.bdResult = $("board-result"); // 計(jì)算機(jī)面板結(jié)果顯示區(qū)對(duì)象
 this.operator = ['+', '-', '×', '÷', '='];
 this.digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']; // 組成有效數(shù)字的數(shù)字?jǐn)?shù)組
 this.dot = '.';
 this.equal = '=';
 this.zero = '0';
 this.digit = "";   // 當(dāng)前輸入的數(shù)字
 this.expression = "";   // 表達(dá)式
 this.resSpan = getResSpan(); // 數(shù)字顯示區(qū)
 this.resDown = $("result-down"); // 表達(dá)式顯示區(qū)
 this.last = "";   // 上一次按下的按鈕內(nèi)容
 this.allDigits = [];   // 從表達(dá)式中獲取的所有數(shù)字組成的數(shù)組,將用來和ops中的操作符對(duì)應(yīng)計(jì)算出結(jié)果 
 this.ops = [];   // 所有操作符組成的數(shù)組
 this.hasEqual = false;  // 判斷是否按下了'='鍵
 this.lastRes = 0;   // 上一次計(jì)算的結(jié)果,即上一次按等號(hào)后計(jì)算出的值
 
 
 // 私有方法
 
}

登錄后復(fù)制

添加點(diǎn)擊事件(注意this在閉包里的引用問題)

// 為td添加點(diǎn)擊事件
Calculator.prototype.addTdClick = function () {
 
 var tds  = $tag("td");
 var that = this; // 需要注意保存this的引用
 // 為每個(gè)td添加點(diǎn)擊事件
 for (var i = 0; i < tds.length; i++) {
 tds[i].onclick = function (){
  // alert(this.innerText);
  var text = this.innerText;
 
  that.calculatorClickEvent(text);
 };
 }
};

登錄后復(fù)制

計(jì)算器點(diǎn)擊事件處理入口

// 計(jì)算器按鈕事件
Calculator.prototype.calculatorClickEvent = function (btnText) {
 
 // 上一個(gè)按鍵是'='
 if (this.hasEqual) {
 this.hasEqual = false;
 this.clearData();
 }
 
 // 結(jié)果顯示在board-result里
 if (btnText != "AC" && btnText != "CE") {
 this.btnClickHanlder(btnText);
 } else { // AC或CE清零
 this.clearData();
 }
};

登錄后復(fù)制

計(jì)算器點(diǎn)擊事件處理程序

// 計(jì)算器的按鍵事件處理
Calculator.prototype.btnClickHanlder = function (btnText) {
 
 if ((btnText >= '0' && btnText <= '9') || btnText == this.dot) { // 數(shù)字鍵處理
 
 // 如果上一個(gè)是操作符,則清空當(dāng)前數(shù)字區(qū)
 if (this.isOperator(this.last)) {
  this.resSpan.innerText = '';
  this.digit = '';
 } else if ((btnText == this.dot) && (this.last == this.dot)) {
  // 如果上一個(gè)也是點(diǎn),則對(duì)本次的點(diǎn)按鈕不做響應(yīng)
  return;
 }
 
 this.digit += btnText;
 this.expression += btnText;
 } else if (this.isOperator(btnText)) { // 操作符處理
 
 // 如果當(dāng)前表達(dá)式為'0',按'=',不給響應(yīng)
 if ((btnText == this.equal) && (this.resDown.innerText == this.zero || this.resDown.innerText == "")) return;
 // 如果上一個(gè)是非'='的操作符則不進(jìn)行處理
 if (!this.isOperator(this.last) && btnText == this.equal) { // '='處理
 
  this.showCurrRes(this.zero, this.expression + btnText); // 計(jì)算結(jié)果顯示在表達(dá)式區(qū)域
  return;
 } else if (this.isOperator(this.last)) {
  // 上一個(gè)是操作符,此次的操作符不做記錄
  return;
 } else {
  this.expression += btnText;
 }
 
 }
 
 this.showCurrRes(this.digit, this.expression);
 
 this.last = btnText;
};

登錄后復(fù)制

處理將要顯示的表達(dá)式和當(dāng)前輸入的數(shù)字

// 顯示當(dāng)前結(jié)果的觸發(fā)方法
Calculator.prototype.showCurrRes = function (digit, expression) {
 
 if (!expression) return;
 
 this.showText(digit, expression);
 
 // 1. 沒有'=',表示還沒有到計(jì)算結(jié)果的時(shí)候,直接退出
 if (expression.indexOf(this.equal) == -1) return;
 
 // 計(jì)算出了結(jié)果
 this.hasEqual = true;
 
 // 2. 處理只按了數(shù)字然后直接按了等號(hào)的情況,即:'234='則直接返回234
 var tmpStr = this.delHeadZero(expression.substr(0, expression.length - 1)); // 去掉最后一個(gè)'='
 if (!this.hasOperator(tmpStr)) {
 this.showText(tmpStr, expression + tmpStr);
 return;
 }
 
 // 3. 處理表達(dá)式字符串,且計(jì)算出結(jié)果
 var start = 0;
 for (var i = 0; i < expression.length; i++) {
 
 var c = expression[i];
 if (this.isOperator(c)) { // 操作符
  this.ops.push(c); // 保存操作符
  var numStr = expression.substr(start, i + 1); // 數(shù)字字符串
  var number = 0;
 
  // 浮點(diǎn)數(shù)和整型處理
  if (numStr.indexOf(this.dot)) {
  number = parseFloat(numStr);
  } else {
  number = parseInt(numStr);
  }
  this.allDigits.push(number); // 保存數(shù)字
  start = i + 1; // 重設(shè)數(shù)字起始位置,即操作符的下一個(gè)字符開始
 }
 }
 
 // 用allDigits和ops去計(jì)算結(jié)果
 var res = this.calResult();
 
 // 保存此次計(jì)算結(jié)果,作為下一次計(jì)算用 [TODO]
 this.lastRes = res;
 
 // 將結(jié)果顯示出來
 this.showText(res + '', expression + res);
};

登錄后復(fù)制

將處理結(jié)果顯示到屏顯區(qū)

// 將表達(dá)式和計(jì)算結(jié)果顯示到屏顯區(qū)
Calculator.prototype.showText = function (digitStr, expression) {
 
 // 先刪除開頭的'0'
 var expStr = this.delHeadZero(expression);
 var digStr = this.delHeadZero(digitStr);
 
 // 然后再根據(jù)情況決定是否添加'0'
 var tmp = expression == this.zero ? expression : this.addZero(expStr);;
 var dig = digitStr == this.zero ? digitStr : this.addZero(digStr);
 
 this.resSpan.innerText = dig;
 
 // 如果表達(dá)式第一個(gè)是操作符,則表示之前按的是'0',則給補(bǔ)上'0',因?yàn)榍懊鎸㈤_頭的'0'都刪掉了
 if (this.isOperator(tmp[0])) {
 tmp = this.zero + tmp;
 }
 
 this.resDown.innerText = tmp;
}

登錄后復(fù)制

計(jì)算結(jié)果函數(shù)

// 計(jì)算結(jié)果
Calculator.prototype.calResult = function () {
 var first = 0;
 var second = 0;
 var res = 0;
 for (var i = 0; i < this.ops.length; i++) {
 first = this.allDigits[i];
 second = this.allDigits[i + 1];
 switch (this.ops[i]) {
  case '+':
  res = first + second;
  break;
  case '-':
  res = first - second;
  break;
  case '×':
  res = first * second;
  break;
  case '÷':
  res = first / second;
  break;
  default:
  break;
 }
 
 this.allDigits[i + 1] = res;
 }
 
 return res;
};

登錄后復(fù)制

清空數(shù)據(jù)

// 計(jì)算完一次,清空所有數(shù)據(jù),以備下次計(jì)算使用
Calculator.prototype.clearData = function () {
 this.allDigits = [];
 this.ops = [];
 this.expression = this.zero;
 this.digit = '';
 
 this.resSpan.innerText = this.zero;
 this.resDown.innerText = this.zero;
};

登錄后復(fù)制

輔助函數(shù)

處理表達(dá)式開頭的'0'問題(第一個(gè)按鈕是0鍵或者第一個(gè)是小于1的浮點(diǎn)數(shù),表達(dá)式需要補(bǔ)零;)

// 開頭添加'0',防止重復(fù)出現(xiàn)或者沒有'0'情況
Calculator.prototype.addZero = function (expression) {
 
 if (!expression) return this.zero;
 
 if (expression[0] == this.dot) { // 浮點(diǎn)數(shù)
 return this.zero + expression;
 } else {
 return expression;
 }
};

登錄后復(fù)制

開頭去零函數(shù)

// 去開頭的零
Calculator.prototype.delHeadZero = function (str) {
 
 // 先把開頭的‘0'都刪掉
 var tmp = "";
 tmp = str.replace(/^[0]+/gi, "");
 if (tmp[0] == this.dot) { // 浮點(diǎn)數(shù)重新補(bǔ)上'0'
 tmp = this.zero + tmp;
 }
 
 return tmp;
};

登錄后復(fù)制

判斷字符串里是否含有操作符

// 判斷表達(dá)式中是否含有操作符
Calculator.prototype.hasOperator = function (str) {
 
 if (!str) return;
 
 for (var i = 0; i < this.operator.length; i++) {
 if (str.indexOf(this.operator[i]) >= 0) {
  return true;
 }
 }
 
 return false;
};

登錄后復(fù)制

其他函數(shù)

// 獲取輸入的數(shù)字顯示區(qū)對(duì)象
function getResSpan() {
 return $("result-up").getElementsByTagName("span")[0];
}
 
// 根據(jù)標(biāo)簽名獲取DOM對(duì)象
function $tag(tagName) {
 return document.getElementsByTagName(tagName);
}
 
// 根據(jù)ID獲取DOM對(duì)象
function $(id) {
 return document.getElementById(id);
}

登錄后復(fù)制

問題

文字底部顯示:通過設(shè)置行高處理;

通過一次性解析表達(dá)式需要考慮表達(dá)式開頭是否需要'0'存在;

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

更多JS 實(shí)現(xiàn)計(jì)算器詳解及實(shí)例代碼(一)相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!

總結(jié)

以上是生活随笔為你收集整理的JS 实现计算器详解及实例代码(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。