계산기의 JS 구현에 대한 자세한 설명 및 예제 코드(1)

高洛峰
풀어 주다: 2017-01-20 17:11:31
원래의
1103명이 탐색했습니다.

Javascript로 계산기 구현:

연재 기사:

JS로 계산기의 자세한 설명과 예제 코드 구현(1)

Javascript로 계산기 시간의 자세한 설명과 예제 구현 function ( 2)

Small JavaScript Calculator

제가 생각해낸 해결책은 완성되었음에도 불구하고 여전히 버그가 많고, 사용하는 방법도 가장 효과적이지는 않습니다. 기본적으로 기능이 완료된 것으로 간주되어 몇 가지 작은 세부 사항이 고려되었지만 아직 처리해야 할 다른 세부 사항이 있습니다.

전체적인 디자인 아이디어는 먼저 스케치를 그리는 것입니다. -> UI 코드 작성 -> JS 로직 코드 작성; 보드)

전체 패널 크기 디자인

JS 实现计算器详解及实例代码(一)제목 표시줄(보드 제목)

글꼴: 글꼴: 30px/50px “Comic Sans MS” , "Microsoft Yahei";

너비 및 높이: (100%, 50px);

화면 표시 영역(보드-결과)

숫자 표시 영역(결과) -up ):

표현식 표시 영역(결과-다운):

버튼 영역(보드-키), 양식을 사용하여 완료한 후 onclick 이벤트 추가

각 td에 인터페이스 완성

JS 实现计算器详解及实例代码(一)새 글꼴 가져오기

// main.css
@font-face {
font-family: Lovelo-Black;/×定义font的名字×/
src: url('font/Lovelo Black.otf');/*把下载的字体文件引入进来×/
}
로그인 후 복사

코드 분석

코드 구성 구조

계산기 개체: 계산기;

계산기 속성:

bdResult: 계산기 패널 화면 표시 영역의 DOM 개체

연산자: 연산 '+,-,×,¶,='을 포함한 문자 배열

숫자: '0-9' 및 점 '.'을 포함한 유효한 숫자 문자

점, 등호, 0: '.', '=', '0'은 점, 등호, 문자 '0'에 해당합니다.

숫자: 현재 입력된 숫자가 상위 레이어에 표시됩니다. 화면 표시 영역

expression: 화면 표시 영역의 하위 레이어에 표시되는 입력 숫자와 연산자로 구성된 표현식

resSpan: 현재 숫자를 표시하는 범위 개체입니다. 화면 표시 영역의 상위 레이어

resDown: 화면 표시 영역의 하위 레이어에 표현식을 표시하는 div 개체

last: 마지막으로 입력된 버튼 내용;

allDigits: 표현식으로 구문 분석된 표현식의 모든 유효한 숫자 ;

ops: 표현식 문자열로 구문 분석된 표현식의 모든 연산자

hasEqual: '=' 여부를 결정합니다. 등호 식별자를 눌렀습니다.

lastRes: 아직 사용되지 않았으며 계속 계산하여 구현할 수 있는 마지막 계산 결과입니다.

계산기 방법:

init: 계산기 초기화 방법;

addTdClick: 각 td, 즉 계산기 버튼에 클릭 이벤트를 추가합니다.

calculatorClickEvent: 클릭 이벤트; 클릭 이벤트 처리 기능

showCurrRes: 화면 표시 영역의 상위 및 하위 레이어에 표시할 내용

showText: showCurrRes에 의해 처리된 결과를 표시합니다. 🎜>addZero: 표현식 앞에 '0' 추가;

calResult: 계산 결과

clearData: 데이터 지우기;

hasOperator: 연산자가 있는지 확인

isOperator: 현재 문자가 연산자인지 확인합니다.

delHeadZero: 표현식 시작 부분의 '0'을 삭제합니다.

보조 메서드

getResSpan: 화면 표시의 상위 레이어에 있는 스팬 개체를 가져옵니다.

$tag: 태그 이름을 기반으로 태그 개체를 가져옵니다.

$: 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;   // 上一次计算的结果,即上一次按等号后计算出的值
 
 
 // 私有方法
 
}
로그인 후 복사

클릭 이벤트 추가(이 항목의 참조 문제에 유의하세요. 클로저에서)

// 为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) {
 
 // 上一个按键是&#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();
 }
};
로그인 후 복사

계산기 클릭 이벤트 handler

// 计算器的按键事件处理
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;
};
로그인 후 복사

는 표시할 표현식과 현재 입력을 처리합니다. 숫자

// 显示当前结果的触发方法
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);
};
로그인 후 복사

처리 결과를 화면 표시부에 표시

// 将表达式和计算结果显示到屏显区
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;
}
로그인 후 복사

계산 결과 기능

// 计算结果
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;
};
로그인 후 복사

데이터 지우기

// 计算完一次,清空所有数据,以备下次计算使用
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' 문제(첫 번째 버튼이 0 키임) 또는 첫 번째가 1보다 작은 부동 소수점 숫자이면 표현식을 0으로 채워야 합니다.)

// 开头添加&#39;0&#39;,防止重复出现或者没有&#39;0&#39;情况
Calculator.prototype.addZero = function (expression) {
 
 if (!expression) return this.zero;
 
 if (expression[0] == this.dot) { // 浮点数
 return this.zero + expression;
 } else {
 return expression;
 }
};
로그인 후 복사

처음에 0 함수 제거

// 去开头的零
Calculator.prototype.delHeadZero = function (str) {
 
 // 先把开头的‘0&#39;都删掉
 var tmp = "";
 tmp = str.replace(/^[0]+/gi, "");
 if (tmp[0] == this.dot) { // 浮点数重新补上&#39;0&#39;
 tmp = this.zero + tmp;
 }
 
 return tmp;
};
로그인 후 복사

문자열에 연산자

// 判断表达式中是否含有操作符
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;
};
로그인 후 복사

기타 함수

// 获取输入的数字显示区对象
function getResSpan() {
 return $("result-up").getElementsByTagName("span")[0];
}
 
// 根据标签名获取DOM对象
function $tag(tagName) {
 return document.getElementsByTagName(tagName);
}
 
// 根据ID获取DOM对象
function $(id) {
 return document.getElementById(id);
}
로그인 후 복사

문제

텍스트 하단 표시: 줄 높이를 설정하여 처리

일회성으로 표현식을 구문 분석할 때 처음에 '0'이 필요한지 고려해야 합니다.

읽어주셔서 감사합니다. 모두에게 도움이 되기를 바랍니다. 이 사이트를 지원해 주셔서 감사합니다!

JS 계산기 구현(1)에 대한 자세한 설명과 예제 코드는 PHP 중국어 홈페이지 관련 글을 참고해주세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿