首頁 > web前端 > js教程 > JS 實作計算器詳解及實例程式碼(一)

JS 實作計算器詳解及實例程式碼(一)

高洛峰
發布: 2017-01-20 17:11:31
原創
1209 人瀏覽過

Javascript 實作計算器:

系列文章:

JS 實作計算器詳解及實例程式碼(一)

Javascript 實作計算器時間功能詳解及實例(二)

小型JavaScript計算器

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

整體設計想法是,先畫草圖-> 設計UI -> 寫UI程式碼-> 寫CSS -> 寫JS邏輯程式碼;

面板(main-board)

面板整體尺寸設計標題

面板(main-board)

JS 实现计算器详解及实例代码(一)面板整體尺寸設計標題

面板整體尺寸設計標題

欄(board-title)

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

寬高:(100%, 50px);

JS 实现计算器详解及实例代码(一)屏顯區(board-result)

數位顯示區(result-up):

表達式顯示區(result-down):

按鈕區(board-keys),使用表格完成,然後將每個td新增onclick事件

完成介面

導入新字體

1

2

3

4

5

// main.css

@font-face {

font-family: Lovelo-Black;/×定义font的名字×/

src: url('font/Lovelo Black.otf');/*把下载的字体文件引入进来×/

}

登入後複製

   

程式碼分析

程式碼組織結構

計算器物件:Calculatora:Re

程式碼組織結構

計算器物件:Calculatora:Re

operator:運算元數組,包括'+,-,×,÷,=';

digits:有效數字字符,包括'0-9'和點'.';

dot, equal, zero:'. ', '=', '0'對應三個字符,點,等號,字符'0';

digit:屏顯區上層的顯示的當前輸入的數字;

expression:屏顯區下層的顯示的輸入的數字和操作符組成的表達式;

resSpan:屏顯區上層的顯示當前數字的span物件;

resDown:屏顯區下層的顯示表達式的div物件;

last:上一次輸入的按鈕內容;

allDigits:用表達式解析出來的表達式中所有的有效數字;

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

hasEqual:判斷是否按了'='等號的識別碼;

lastRes:上一次計算出來的結果[TODO],尚未用到,待實作可以連續計算;

計算器方法:

init:計算器初始化方法;

addTdClick:為每個td即計算器按鈕新增點擊事件;

calculatorClickEvent:點擊事件;

btnClickHanlder:點擊事件處理函數;

showCurrRes:處理屏幕上將上層和下層屏幕將要顯示的內容; :將通過showCurrRes處理的結果顯示出來;

addZero:對錶達式前面加'0'操作;

calResult:計算結果;

clearData:清空數據;

hasOperator:判斷表達式中是否有操作符;

isOperator:判斷當前字元是否為操作符;

delHeadZero:刪除表達式開頭的'0';

輔助方法

getResSpan:獲取螢幕顯上層的s去取得標籤物件;

$:根據id去取得DOM物件;

程式碼邏輯

使用方法

引入Calculator.js檔案(在編寫完UI的基礎上)

建立物件並初始化:new Caljs檔案( ).init();

計算器物件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// 计算器对象

function Calculator() {

  

 // 私有属性

 this.bdResult = $("board-result"); // 计算机面板结果显示区对象

 this.operator = ['+', '-', '×', '÷', '='];

 this.digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']; // 组成有效数字的数字数组

 this.dot = '.';

 this.equal = '=';

 this.zero = '0';

 this.digit = "";   // 当前输入的数字

 this.expression = "";   // 表达式

 this.resSpan = getResSpan(); // 数字显示区

 this.resDown = $("result-down"); // 表达式显示区

 this.last = "";   // 上一次按下的按钮内容

 this.allDigits = [];   // 从表达式中获取的所有数字组成的数组,将用来和ops中的操作符对应计算出结果

 this.ops = [];   // 所有操作符组成的数组

 this.hasEqual = false;  // 判断是否按下了'='键

 this.lastRes = 0;   // 上一次计算的结果,即上一次按等号后计算出的值

  

  

 // 私有方法

  

}

登入後複製

   

新增點擊事件(注意this在閉包裡的引用問題)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// 为td添加点击事件

Calculator.prototype.addTdClick = function () {

  

 var tds  = $tag("td");

 var that = this; // 需要注意保存this的引用

 // 为每个td添加点击事件

 for (var i = 0; i < tds.length; i++) {

 tds[i].onclick = function (){

  // alert(this.innerText);

  var text = this.innerText;

  

  that.calculatorClickEvent(text);

 };

 }

};

登入後複製

 

計算器點擊事件處理程序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 计算器按钮事件

Calculator.prototype.calculatorClickEvent = function (btnText) {

  

 // 上一个按键是&#39;=&#39;

 if (this.hasEqual) {

 this.hasEqual = false;

 this.clearData();

 }

  

 // 结果显示在board-result里

 if (btnText != "AC" && btnText != "CE") {

 this.btnClickHanlder(btnText);

 } else { // AC或CE清零

 this.clearData();

 }

};

登入後複製

   

處理將要顯示的表達式和目前輸入的數字

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

// 计算器的按键事件处理

Calculator.prototype.btnClickHanlder = function (btnText) {

  

 if ((btnText >= &#39;0&#39; && btnText <= &#39;9&#39;) || btnText == this.dot) { // 数字键处理

  

 // 如果上一个是操作符,则清空当前数字区

 if (this.isOperator(this.last)) {

  this.resSpan.innerText = &#39;&#39;;

  this.digit = &#39;&#39;;

 } else if ((btnText == this.dot) && (this.last == this.dot)) {

  // 如果上一个也是点,则对本次的点按钮不做响应

  return;

 }

  

 this.digit += btnText;

 this.expression += btnText;

 } else if (this.isOperator(btnText)) { // 操作符处理

  

 // 如果当前表达式为&#39;0&#39;,按&#39;=&#39;,不给响应

 if ((btnText == this.equal) && (this.resDown.innerText == this.zero || this.resDown.innerText == "")) return;

 // 如果上一个是非&#39;=&#39;的操作符则不进行处理

 if (!this.isOperator(this.last) && btnText == this.equal) { // &#39;=&#39;处理

  

  this.showCurrRes(this.zero, this.expression + btnText); // 计算结果显示在表达式区域

  return;

 } else if (this.isOperator(this.last)) {

  // 上一个是操作符,此次的操作符不做记录

  return;

 } else {

  this.expression += btnText;

 }

  

 }

  

 this.showCurrRes(this.digit, this.expression);

  

 this.last = btnText;

};

登入後複製

   

計算結果函數

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

// 显示当前结果的触发方法

Calculator.prototype.showCurrRes = function (digit, expression) {

  

 if (!expression) return;

  

 this.showText(digit, expression);

  

 // 1. 没有&#39;=&#39;,表示还没有到计算结果的时候,直接退出

 if (expression.indexOf(this.equal) == -1) return;

  

 // 计算出了结果

 this.hasEqual = true;

  

 // 2. 处理只按了数字然后直接按了等号的情况,即:&#39;234=&#39;则直接返回234

 var tmpStr = this.delHeadZero(expression.substr(0, expression.length - 1)); // 去掉最后一个&#39;=&#39;

 if (!this.hasOperator(tmpStr)) {

 this.showText(tmpStr, expression + tmpStr);

 return;

 }

  

 // 3. 处理表达式字符串,且计算出结果

 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); // 数字字符串

  var number = 0;

  

  // 浮点数和整型处理

  if (numStr.indexOf(this.dot)) {

  number = parseFloat(numStr);

  } else {

  number = parseInt(numStr);

  }

  this.allDigits.push(number); // 保存数字

  start = i + 1; // 重设数字起始位置,即操作符的下一个字符开始

 }

 }

  

 // 用allDigits和ops去计算结果

 var res = this.calResult();

  

 // 保存此次计算结果,作为下一次计算用 [TODO]

 this.lastRes = res;

  

 // 将结果显示出来

 this.showText(res + &#39;&#39;, expression + res);

};

登入後複製

   

清空資料

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// 将表达式和计算结果显示到屏显区

Calculator.prototype.showText = function (digitStr, expression) {

  

 // 先删除开头的&#39;0&#39;

 var expStr = this.delHeadZero(expression);

 var digStr = this.delHeadZero(digitStr);

  

 // 然后再根据情况决定是否添加&#39;0&#39;

 var tmp = expression == this.zero ? expression : this.addZero(expStr);;

 var dig = digitStr == this.zero ? digitStr : this.addZero(digStr);

  

 this.resSpan.innerText = dig;

  

 // 如果表达式第一个是操作符,则表示之前按的是&#39;0&#39;,则给补上&#39;0&#39;,因为前面将开头的&#39;0&#39;都删掉了

 if (this.isOperator(tmp[0])) {

 tmp = this.zero + tmp;

 }

  

 this.resDown.innerText = tmp;

}

登入後複製

   

輔助函數

式需要補零;)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

// 计算结果

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 &#39;+&#39;:

  res = first + second;

  break;

  case &#39;-&#39;:

  res = first - second;

  break;

  case &#39;×&#39;:

  res = first * second;

  break;

  case &#39;÷&#39;:

  res = first / second;

  break;

  default:

  break;

 }

  

 this.allDigits[i + 1] = res;

 }

  

 return res;

};

登入後複製

   

開頭去零函數

1

2

3

4

5

6

7

8

9

10

// 计算完一次,清空所有数据,以备下次计算使用

Calculator.prototype.clearData = function () {

 this.allDigits = [];

 this.ops = [];

 this.expression = this.zero;

 this.digit = &#39;&#39;;

  

 this.resSpan.innerText = this.zero;

 this.resDown.innerText = this.zero;

};

登入後複製

   

   

問題

文字底部顯示:透過設定行高處理;

透過一次性解析表達式需要考慮表達式開頭是否需要'0'存在;

感謝閱讀,希望能幫助大家,謝謝大家對本站的支持!

更多JS 實作計算器詳解及實例程式碼(一)相關文章請關注PHP中文網!

相關標籤:
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板