小型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/Lovelo Black.otf');/*把下载的字体文件引入进来×/ }
代码分析
代码组织结构
计算器对象:Calculator;
计算器属性:
bdResult: 计算器面板上的屏显区DOM对象;
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:处理屏显区上层和下层将要显示的内容;
showText:将通过showCurrRes处理的结果显示出来;
addZero:对表达式前面加'0'操作;
calResult:计算结果;
clearData:清空数据;
hasOperator:判断表达式中是否有操作符;
isOperator:判断当前字符是否是操作符;
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 = '='; 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在闭包里的引用问题)
// 为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(); } };
计算器点击事件处理程序