JS实现计算器详解及实例代码(⼀)
Javascript 实现计算器:
系列⽂章:
⼩型JavaScript计算器
⾃⼰寻思出的解决⽅案,⽐较笨拙的⽅法,虽然完成了但是还有不少bug,⽤的⽅法也不是最有效的,基本功能算是完成了,⼀些⼩的细节地⽅也考虑到了,但是还有其他的细节需要处理。
总体设计思路是,先画草图 -> 设计UI -> 编写UI代码 -> 编写CSS -> 编写JS逻辑代码;
⾯板(main-board)
⾯板整体尺⼨设计
标题栏(board-title)
字体: font: 30px/50px “Comic Sans MS”, “微软雅⿊”;
宽⾼:(100%, 50px);
屏显区(board-result)
数字显⽰区(result-up):
表达式显⽰区(result-down):
按钮区(board-keys),使⽤表格完成,然后给每个td添加onclick事件
完成界⾯
导⼊新字体
// main.css
@font-face {
font-family: Lovelo-Black;/×定义font的名字×/
src: url('font/f');/*把下载的字体⽂件引⼊进来×/
}
代码分析
代码组织结构
计算器对象:Calculator;
计算器属性:
bdResult: 计算器⾯板上的屏显区DOM对象;
operator:操作符数组,包括'+,-,×,÷,=';
digits:有效数字字符,包括'0-9'和点'.';
dot, equal, zero:'.', ‘=', ‘0'对应三个字符,点,等号,字符'0';
digit:屏显区上层的显⽰的当前输⼊的数字;
expression:屏显区下层的显⽰的输⼊的数字和操作符组成的表达式;
resSpan:屏显区上层的显⽰当前数字的span对象;
resDown:屏显区下层的显⽰表达式的div对象;
last:上⼀次输⼊的按钮内容;
allDigits:⽤表达式解析出来的表达式中所有的有效数字;
ops:⽤表达式字符串解析出来的表达式中所有的操作符;
hasEqual:判断是否按了'='等号的标识符;
lastRes:上⼀次计算出来的结果[TODO],尚未⽤到,待实现可以连续计算;计算器⽅法:
1. init:计算器初始化⽅法;
2. addTdClick:给每个td即计算器按钮添加点击事件;
3. calculatorClickEvent:点击事件;
4. btnClickHanlder:点击事件处理函数;
5. showCurrRes:处理屏显区上层和下层将要显⽰的内容;
6. showText:将通过showCurrRes处理的结果显⽰出来;
7. addZero:对表达式前⾯加'0'操作;
8. calResult:计算结果;
9. clearData:清空数据;
10. hasOperator:判断表达式中是否有操作符;
11. isOperator:判断当前字符是否是操作符;
12. delHeadZero:删除表达式开头的'0';
辅助⽅法
getResSpan:获取屏显上层的span对象;
$tag:根据标签名去获取标签对象;
$:根据id去获取DOM对象;
代码逻辑
使⽤⽅法
引⼊Calculator.js⽂件(在编写完UI的基础上)
创建对象并初始化:new Calculator().init();
计算器对象
/
/ 计算器对象
function Calculator() {
// 私有属性
this.bdResult = $("board-result"); // 计算机⾯板结果显⽰区对象
this.operator = ['+', '-', '×', '÷', '='];
this.digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']; // 组成有效数字的数字数组
this.dot = '.';
this.equal = '=';
< = '0';
this.digit = ""; // 当前输⼊的数字
this.last = ""; // 上⼀次按下的按钮内容
this.allDigits = []; // 从表达式中获取的所有数字组成的数组,将⽤来和ops中的操作符对应计算出结果 this.ops = []; // 所有操作符组成的数组
this.hasEqual = false; // 判断是否按下了'='键
this.lastRes = 0; // 上⼀次计算的结果,即上⼀次按等号后计算出的值
// 私有⽅法
}
添加点击事件(注意this在闭包⾥的引⽤问题)
// 为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);
};
}
};
计算器点击事件处理⼊⼝
// 计算器按钮事件
Calculator.prototype.calculatorClickEvent = function (btnText) {
// 上⼀个按键是'='
if (this.hasEqual) {
this.hasEqual = false;
this.clearData();
}
// 结果显⽰在board-result⾥
if (btnText != "AC" && btnText != "CE") {
this.btnClickHanlder(btnText);
} else { // AC或CE清零
this.clearData();
}
};
计算器点击事件处理程序
// 计算器的按键事件处理
Calculator.prototype.btnClickHanlder = function (btnText) {
if ((btnText >= '0' && btnText <= '9') || btnText == this.dot) { // 数字键处理
// 如果上⼀个是操作符,则清空当前数字区
if (this.isOperator(this.last)) {
this.digit = '';
} else if ((btnText == this.dot) && (this.last == this.dot)) {
// 如果上⼀个也是点,则对本次的点按钮不做响应
return;
}
this.digit += btnText;
} else if (this.isOperator(btnText)) { // 操作符处理
// 如果当前表达式为'0',按'=',不给响应
if ((btnText == this.equal) && (sDown.innerText == || sDown.innerText == "")) return; // 如果上⼀个是⾮'='的操作符则不进⾏处理
if (!this.isOperator(this.last) && btnText == this.equal) { // '='处理
this., pression + btnText); // 计算结果显⽰在表达式区域
return;
} else if (this.isOperator(this.last)) {
// 上⼀个是操作符,此次的操作符不做记录
return;
} else {
}
}
this.showCurrRes(this.digit, pression);
this.last = btnText;
};
处理将要显⽰的表达式和当前输⼊的数字
// 显⽰当前结果的触发⽅法
Calculator.prototype.showCurrRes = function (digit, expression) {
if (!expression) return;
this.showText(digit, expression);
// 1. 没有'=',表⽰还没有到计算结果的时候,直接退出
if (expression.indexOf(this.equal) == -1) return;
// 计算出了结果
this.hasEqual = true;
// 2. 处理只按了数字然后直接按了等号的情况,即:'234='则直接返回234
var tmpStr = this.delHeadZero(expression.substr(0, expression.length - 1)); // 去掉最后⼀个'='
if (!this.hasOperator(tmpStr)) {
this.showText(tmpStr, expression + tmpStr);
return;
}
// 3. 处理表达式字符串,且计算出结果
var start = 0;
网站底部代码js特效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 + '', expression + res);
};
将处理结果显⽰到屏显区
// 将表达式和计算结果显⽰到屏显区
Calculator.prototype.showText = function (digitStr, expression) {
/
/ 先删除开头的'0'
var expStr = this.delHeadZero(expression);
var digStr = this.delHeadZero(digitStr);
// 然后再根据情况决定是否添加'0'
var tmp = expression == ? expression : this.addZero(expStr);;
var dig = digitStr == ? digitStr : this.addZero(digStr);
// 如果表达式第⼀个是操作符,则表⽰之前按的是'0',则给补上'0',因为前⾯将开头的'0'都删掉了
if (this.isOperator(tmp[0])) {
tmp = + tmp;
}
}
计算结果函数
// 计算结果
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;
};
清空数据
// 计算完⼀次,清空所有数据,以备下次计算使⽤
Calculator.prototype.clearData = function () {
this.allDigits = [];
this.ops = [];
this.digit = '';
};
辅助函数
处理表达式开头的'0'问题(第⼀个按钮是0键或者第⼀个是⼩于1的浮点数,表达式需要补零;) // 开头添加'0',防⽌重复出现或者没有'0'情况
Calculator.prototype.addZero = function (expression) {
if (!expression) ;
if (expression[0] == this.dot) { // 浮点数
+ expression;
} else {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论