<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css"> body {
padding: 20px;
font-family: Arial;
} .calc-wrap {
width: 300px;
border: 1px solid #ddd;
border-radius: 3px;
} .calc-operation {
width: 100%;
border-collapse: collapse;
} .calc-in-out {
width: 100%;
padding: 10px 20px;
text-align: right;
box-sizing: border-box;
background-color: rgba(250, 250, 250, .9);
}
.calc-in-out p {
overflow: hidden;
margin: 5px;
width: 100%;
}
.calc-history {
margin-left: -20px;
font-size: 18px;
color: #bbb;
border-bottom: 1px dotted #ddf;
min-height: 23px;
} .calc-in,
.calc-out {
font-size: 20px;
color: #888;
line-height: 39px;
min-height: 39px;
} .calc-in {
color: #888;
}
.calc-out {
color: #ccc;
} .calc-in.active,
.calc-out.active {
font-size: 34px;
color: #666;
} .calc-operation td {
padding: 10px;
width: 25%;
text-align: center;
border: 1px solid #ddd;
font-size: 26px;
color: #888;
cursor: pointer;
} .calc-operation td:active {
background-color: #ddd;
} .calc-operation .cls {
color: #ee8956;
}
</style>
<script src="../jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function() {
function Calculator($dom) {
this.$dom = $($dom);
// 历史运算
this.$history = this.$dom.find('.calc-history');
// 输入区
this.$in = this.$dom.find('.calc-in');
// 输出区
this.$out = this.$dom.find('.calc-out');
this.$operation = this.$dom.find('.calc-operation'); // 运算符映射
this.op = {
'plus': '+',
'minus': '-',
'mul': '*',
'div': '/'
};
this.opArr = ['+', '-', '*', '/']; // 中缀表达式
this.infix = [];
// 后缀表达式
this.suffix = [];
// 后缀表达式运算结果集
this.result = [];
// 存储最近的值
this.lastVal = 0;
// 当前已经计算等于完成
this.calcDone = false;
// 当前正在进行小数点点(.)相关值的修正
this.curDot = false; this.init();
} Calculator.prototype = {
constructor: Calculator,
// 初始化
init: function() {
this.bindEvent();
},
// 绑定事件
bindEvent: function() {
var that = this; that.$operation.on('click', function(e) {
e = e || window.event;
var elem = e.target || e.srcElement,
val,
action; if (elem.tagName === 'TD') {
val = elem.getAttribute('data-val') || elem.getAttribute('data-ac');
// 数字:0-9
if (!isNaN(parseInt(val, 10))) {
// 构建中缀表达式并显示
var infixRe = that.buildInfix(parseInt(val, 10), 'add');
that.$in.text(infixRe.join('')).addClass('active'); that.calculate(); return;
} action = val; // 操作:清除、删除、计算等于
if (['cls', 'del', 'eq'].indexOf(action) !== -1) {
if (!that.infix.length) {
return;
} // 清空数据
if (action === 'cls' || (action === 'del' && that.calcDone)) {
that.$in.text('');
that.$out.text(''); that.resetData();
}
// 清除
else if (action === 'del') {
// 重新构建中缀表达式
var infixRe = that.buildInfix(that.op[action], 'del');
that.$in.text(infixRe.join('')).addClass('active'); that.calculate(); }
// 等于
else if (action === 'eq') {
that.calculate('eq'); }
}
// 预运算:百分比、小数点、平方
else if (['per', 'dot', 'sq'].indexOf(action) !== -1) {
if (!that.infix.length || that.isOp(that.lastVal)) {
return;
} if (action === 'per') {
that.lastVal /= 100;
} else if (action === 'sq') {
that.lastVal *= that.lastVal;
} else if (action === 'dot') {
// that.curDot = true;
} // 重新构建中缀表达式
var infixRe = that.buildInfix(that.lastVal, 'change');
that.$in.text(infixRe.join('')).addClass('active'); that.calculate();
}
// 运算符:+ - * /
else if (that.isOp(that.op[action])) {
if (!that.infix.length && (that.op[action] === '*' || that.op[action] === '/')) {
return;
} var infixRe = that.buildInfix(that.op[action], 'add');
that.$in.text(infixRe.join('')).addClass('active');
}
}
});
}, resetData: function() {
this.infix = [];
this.suffix = [];
this.result = [];
this.lastVal = 0;
this.curDot = false;
}, // 构建中缀表达式
buildInfix: function(val, type) {
// 直接的点击等于运算之后,
if (this.calcDone) {
this.calcDone = false;
// 再点击数字,则进行新的运算
if (!this.isOp(val)) {
this.resetData();
}
// 再点击运算符,则使用当前的结果值继续进行运算
else {
var re = this.result[0];
this.resetData();
this.infix.push(re);
} } var newVal; // 删除操作
if (type === 'del') {
newVal = this.infix.pop();
// 删除末尾一位数
newVal = Math.floor(newVal / 10);
if (newVal) {
this.infix.push(newVal);
} this.lastVal = this.infix[this.infix.length - 1];
return this.infix;
}
// 添加操作,首先得判断运算符是否重复
else if (type === 'add') {
// 两个连续的运算符
if (this.isOp(val) && this.isOp(this.lastVal)) {
return this.infix;
}
// 两个连续的数字
else if (!this.isOp(val) && !this.isOp(this.lastVal)) {
newVal = this.lastVal * 10 + val;
this.infix.pop();
this.infix.push(this.lastVal = newVal); return this.infix;
}
// 首个数字正负数
if (!this.isOp(val) && this.infix.length === 1 && (this.lastVal === '+' || this.lastVal === '-')) {
newVal = this.lastVal === '+' ? val : 0 - val;
this.infix.pop();
this.infix.push(this.lastVal = newVal); return this.infix;
} this.infix.push(this.lastVal = val);
return this.infix;
} // 更改操作,比如%的预运算
else if (type === 'change') {
this.infix.pop();
this.infix.push(this.lastVal = val); return this.infix;
} },
// 判断是否为运算符
isOp: function(op) {
return op && this.opArr.indexOf(op) !== -1;
},
// 判断运算符优先级
priorHigher: function(a, b) {
return (a === '+' || a === '-') && (b === '*' || b === '/');
},
// 进行运算符的运算
opCalc: function(b, op, a) {
return op === '+'
? a + b
: op === '-'
? a - b
: op === '*'
? a * b
: op === '/'
? a / b
: 0;
},
// 即时得进行运算
calculate: function(type) {
this.infix2Suffix();
var suffixRe = this.calcSuffix(); if (suffixRe) {
this.$out.text('=' + suffixRe)
.attr('title', suffixRe)
.removeClass('active'); // 如果是直接显示地进行等于运算
if (type === 'eq') {
this.$in.removeClass('active');
this.$out.addClass('active');
// 设置标记:当前已经显示地进行计算
this.calcDone = true;
this.lastVal = suffixRe;
// 设置历史记录
var history = this.infix.join('') + ' = ' + suffixRe;
this.$history.text(history).attr('title', history);
} }
}, // 中缀表达式转后缀
infix2Suffix: function() {
var temp = [];
this.suffix = []; for (var i = 0; i < this.infix.length; i++) {
// 数值,直接压入
if (!this.isOp(this.infix[i])) {
this.suffix.push(this.infix[i]);
}
else {
if (!temp.length) {
temp.push(this.infix[i]);
}
else {
var opTop = temp[temp.length - 1];
// 循环判断运算符优先级,将运算符较高的压入后缀表达式
if (!this.priorHigher(opTop, this.infix[i])) {
while (temp.length && !this.priorHigher(opTop, this.infix[i])) {
this.suffix.push(temp.pop());
opTop = temp[temp.length - 1];
}
}
// 将当前运算符也压入后缀表达式
temp.push(this.infix[i]);
}
}
}
// 将剩余运算符号压入
while (temp.length) {
this.suffix.push(temp.pop());
}
}, // 后缀表达式计算
calcSuffix: function() {
this.result = []; for (var i = 0; i < this.suffix.length; i++) {
// 数值,直接压入结果集
if (!this.isOp(this.suffix[i])) {
this.result.push(this.suffix[i]);
}
// 运算符,从结果集中取出两项进行运算,并将运算结果置入结果集合
else {
this.result.push(this.opCalc(this.result.pop(), this.suffix[i], this.result.pop()));
}
}
// 此时结果集中只有一个值,即为结果
return this.result[0];
}
}; new Calculator('.calc-wrap');
});
</script>
</head>
<body>
<!-- 计算器 -->
<div class="calc-wrap">
<div class="calc-in-out">
<!-- 上一条运算记录 -->
<p class="calc-history" title=""></p>
<!-- 输入的数据 -->
<p class="calc-in"></p>
<!-- 输出的运算结果 -->
<p class="calc-out active"></p>
</div>
<table class="calc-operation">
<thead></thead>
<tbody>
<tr>
<td data-ac="cls" class="cls">C</td>
<td data-ac="del">&larr;</td>
<td data-ac="sq">x<sup>2</sup></td>
<td data-ac="mul">&times;</td>
</tr>
<tr>
<td data-val="7">7</td>
<td data-val="8">8</td>
<td data-val="9">9</td>
<td data-ac="div">&divide;</td>
</tr>
<tr>
<td data-val="4">4</td>
<td data-val="5">5</td>
<td data-val="6">6</td>
<td data-ac="plus">+</td>
</tr>
<tr>
<td data-val="1">1</td>
<td data-val="2">2</td>
<td data-val="3">3</td>
<td data-ac="minus">-</td>
</tr>
<td data-ac="per">%</td>
<td data-val="0">0</td>
<td data-ac="dot">.</td>
<td data-ac="eq" class="eq">=</td>
</tbody>
</table>
</div>
</body>
</html>

jquery实现简易的计算器的更多相关文章

  1. 03-c#入门(简易存款利息计算器v1.0)

    本想把练习题做了的结果放上来,不过发现附录是有答案的,就算了吧,自己做了没问题就行了哈.之前提到过,要是有朋友有想法,需要做小工具我可以帮忙实现,不过貌似大家都很忙.SO,自己学完第4章后,决定做一个 ...

  2. iOS:制作一个简易的计算器

    初步接触视图,制作了一个简易的计算器,基本上简单的计算是没有问题的,不是很完美,可能还有一些bug,再接再厉. // // ViewController.m // 计算器 // // Created ...

  3. 手写实现java栈结构,并实现简易的计算器(基于后缀算法)

    一.定义 栈是一种线性表结构,栈结构中有两端,对栈的操作都是对栈的一端进行操作的,那么被操作的一端称为栈顶,另一端则为栈底.对栈的操作其实就是只有两种,分别是入栈(也称为压栈)和出栈(也称为弹栈).入 ...

  4. 利用Unity3D制作简易2D计算器

    利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...

  5. 基于jQuery的简易瀑布流实现

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. jQuery实现简易轮播图的效果

    (图片素材取自于小米官网) 刚开始接触jQuery的学习,个人觉得如果为了实现多数的动态效果,jQuery的确很简易方便. 下面简易的轮播图效果,还请前辈多多指教~ (努力学习react vue an ...

  7. 简易Servlet计算器1.0

    编写一个简易的Servlet计算器,暂时仅能实现 + - * / % 五种运算 jsp界面: <%@ page language="java" contentType=&qu ...

  8. JS实现简易的计算器

    JS可以做的事多了,那就用来实现一个计算器吧 看看手机中的计算器,分为普通计算器和科学计算器     自认脑袋不够大,就实现一个普通版本的吧(支持正负数加减乘除等基本连续的运算,未提供括号功能) 看看 ...

  9. 简易servlet计算器

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

随机推荐

  1. 647. Palindromic Substrings 互文的子字符串

    [抄题]: Given a string, your task is to count how many palindromic substrings in this string. The subs ...

  2. 14-敌兵布阵(HDU1166线段树 & 树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory ...

  3. linux操作系统下,怎么使用kill按照PID一次杀死多个进程

    1.ps -ef | grep firefox | grep -v grep | cut -c 9-15 | xargs kill -s 9 说明:“grep firefox”的输出结果是,所有含有关 ...

  4. 独立看门狗实验-IWDG

    为什么要看门狗? 注意:喂狗是0XAAAA写到KR. 头文件iwdg.h iwdg.c

  5. JSTL详解实例

    JSTL标签库的使用是为类弥补html表的不足,规范自定义标签的使用而诞生的.在告别modle1模式开发应用程序后,人们开始注重软件的分层设计,不希望在jsp页面中出现java逻辑代码,同时也由于自定 ...

  6. centos环境下如何导出数据库

    MySQL数据库的导入导出可以用数据库备份工具mysqldump mysqldump工具是mysql自带的一个非常方便的一款小工具,存在mysql安装目录的/usr/local/mysql/bin ( ...

  7. (二)ASP.NET中JavaScript的中英文(多语言)实现方案(二)

    在ASP.NET中JavaScript的中英文(多语言)实现方案中简单的介绍了js实现多语言的一种方案.下面将要讲述另外一种方法,尽管很相似,但是有些地方也是需要细细琢磨的,不说了,先看看. 在Lan ...

  8. 安装并使用PICT,生成测试用例

    一.PICT简介 PICT工具是在微软公司内部使用的一款承兑组合的命令行生成工具,现在已经对外提供,可以在 http://download.microsoft.com/download/f/5/5/f ...

  9. git 恢复被修改的文件

    恢复到最后一次提交的改动:   git checkout filename 如果该文件已经 add 到暂存队列中,恢复文件:   git reset HEAD filename

  10. Oracle数据表转换为Shapefile(一)

    严格来说,文章标题中的“转换”并不完全合适.本文的主要内容是基于Oracle数据表的数据来生产出Shapefile文件.进行该工作的一个前提条件是:Oracle数据表中包含坐标数值字段,一般来说就是x ...