效果图如下:
思路:
首先是用html和css制作计算器的外观,通过js实现用户与计算器之间的交互,实现简单的计算
HTML:
显示部分用input实现,用readonly属性使其不可点击,通过js对value进行改变并显示。按键全部为buton属性
<!DOCTYPE html>
<html>
<head>
<title>Simple Caculator</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="outlooking.css">
<link href="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3769137495,1031451634&fm=27&gp=0.jpg" type="image/gif" rel="icon">
<script type="text/javascript" src="cacuScript.js"></script>
</head>
<body>
<div id="caculator">
<button id="tip" onclick="readme()">R</button>
<div id="headline">Simple Caculator</div>
<div id="empty_field"></div>
<div id="output_field">
<input type="text" id="output" value=" " readonly="readonly">
</div>
<div id="button_field">
<table>
<tr>
<td><button value="7" id="7" class="num">7</button></td>
<td><button value="8" id="8" class="num">8</button></td>
<td><button value="9" id="9" class="num">9</button></td>
<td><button value="/" id="/" class="operator">/</button></td>
</tr>
<tr>
<td><button value="4" id="4" class="num">4</button></td>
<td><button value="5" id="5" class="num">5</button></td>
<td><button value="6" id="6" class="num">6</button></td>
<td><button value="*" id="*" class="operator">*</button></td>
</tr>
<tr>
<td><button value="1" id="1" class="num">1</button></td>
<td><button value="2" id="2" class="num">2</button></td>
<td><button value="3" id="3" class="num">3</button></td>
<td><button value="-" id="-" class="operator">-</button></td>
</tr>
<tr>
<td><button value="0" id="0" class="num">0</button></td>
<td><button value="." id="." class="num">.</button></td>
<td><button value="←" id="←" class="clean">←</button></td>
<td><button value="+" id="+" class="operator">+</button></td>
</tr>
<tr>
<td><button value="(" id="(" class="num">(</button></td>
<td><button value=")" id=")" class="num">)</button></td>
<td><button value="CE" id="CE" class="clean">CE</button></td>
<td><button value="=" id="=" class="operator">=</button></td>
</tr>
</table>
</div>
</div>
</body>
</html>
CSS:
对网页全局设置将计算器居中显示,计算器采用绝对定位方式,内部按键的分布使用table
html, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
background-image: url(http://img2.imgtn.bdimg.com/it/u=4287441032,4036852516&fm=27&gp=0.jpg);
}
button, input {
outline: none;
}
#caculator {
position: absolute;
padding: 10px;
left: 37%;
top: 10%;
width: 26%;
text-align: center;
border-radius: 20px;
border-color: gray;
border-width: 3px;
border-style: solid;
background-color: #EDF1F4;
box-shadow: inset 0px 0px 20px 0px #000;
}
#headline {
float: right;
font-size: 15px;
font-weight: bold;
color: lightgray;
}
#empty_field {
height: 40px;
margin-top: 8px;
margin-bottom: 8px;
}
#tip {
float: left;
width: 40px;
height: 40px;
border-style: outset;
border-width: 1px;
background-color: #F0F0F0;
border-radius: 50%;
box-shadow: inset 0px 0px 8px 0px #000;
color: #F0F0F0;
font-width: bold;
text-shadow: 1px 1px 3px #666666, -1px -1px 3px #FFFFFF;
}
#tip:hover {
background-color: #FFFFFF;
}
#output_field {
height: 50px;
margin-left: 10px;
margin-right: 10px;
border-radius: 20px;
border-color: gray;
border-width: 3px;
border-style: groove;
background-color: white;
}
#output {
width: 98%;
height: 48px;
border-style: none;
border-radius: 10px;
font-size: 30px;
text-align: right;
}
#button_field {
margin-top: 20px;
margin-bottom: 8px;
width: 100%;
}
#button_field table {
width: 100%;
}
#button_field td {
width: 25%;
padding: 2px;
}
#button_field table button {
width: 90%;
height: 55px;
border-radius: 10px;
box-shadow: inset 0px 0px 12px 0px #000;
font-size: 30px;
}
.clean{
background-color: #668CA3;
}
.operator {
background-color: #B0B0B0;
}
.clean:hover {
background-color: #B7DFEE;
}
.num:hover {
background-color: #F4F4F4;
}
.operator:hover {
background-color: #E0E0E0;
}
JavaScript:
onclick实现按键点击触发输入效果,eval函数实现输入算式的计算,当中有很多的不合法算式没有进行判断,后续要加上判断条件,以及精度问题没有很好处理
var num = 0;
window.onload = function() {
document.getElementById("1").onclick = function() {
getCommand(this.id);
}
document.getElementById("2").onclick = function() {
getCommand(this.id);
}
document.getElementById("3").onclick = function() {
getCommand(this.id);
}
document.getElementById("4").onclick = function() {
getCommand(this.id);
}
document.getElementById("5").onclick = function() {
getCommand(this.id);
}
document.getElementById("6").onclick = function() {
getCommand(this.id);
}
document.getElementById("7").onclick = function() {
getCommand(this.id);
}
document.getElementById("8").onclick = function() {
getCommand(this.id);
}
document.getElementById("9").onclick = function() {
getCommand(this.id);
}
document.getElementById("0").onclick = function() {
getCommand(this.id);
}
document.getElementById(".").onclick = function() {
getCommand(this.id);
}
document.getElementById("+").onclick = function() {
getCommand(this.id);
}
document.getElementById("-").onclick = function() {
getCommand(this.id);
}
document.getElementById("*").onclick = function() {
getCommand(this.id);
}
document.getElementById("/").onclick = function() {
getCommand(this.id);
}
document.getElementById("(").onclick = function() {
getCommand(this.id);
}
document.getElementById(")").onclick = function() {
getCommand(this.id);
}
document.getElementById("←").onclick = function() {
getCommand(this.id);
}
document.getElementById("CE").onclick = function() {
getCommand(this.id);
}
document.getElementById("=").onclick = function() {
getCommand(this.id);
}
}
document.onkeydown = function(event){
var e = event || window.event || arguments.callee.caller.arguments[0];
if (e.keyCode == 13 || e.keyCode == 108) getCommand('=');
else if (e.keyCode == 8) getCommand('←');
else if (e.keyCode == 107 || e.keyCode == 187 && e.shiftKey) getCommand('+');
else if (e.keyCode == 109 || e.keyCode == 189) getCommand('-');
else if (e.keyCode == 106 || e.keyCode == 56 && e.shiftKey) getCommand('*');
else if (e.keyCode == 111 || e.keyCode == 191) getCommand('/');
else if (e.keyCode == 110 || e.keyCode == 190) getCommand('.');
else if (e.keyCode == 48 && e.shiftKey) getCommand(')');
else if (e.keyCode == 57 && e.shiftKey) getCommand('(');
else if (e.keyCode >= 48 && e.keyCode <= 57) getCommand(e.keyCode - 48);
else if (e.keyCode >= 96 && e.keyCode <= 105) getCommand(e.keyCode - 96);
else if (e.keyCode < 37 || e.keyCode > 40 && e.keyCode < 48 || e.keyCode > 57 && e.keyCode < 96 || e.keyCode > 123) window.event.returnValue = false;
}
function readme() {
alert("Simple Caculator - Readme @Treek\n\n\n"+
"目前实现功能:\n"+
"1.运算、清屏、退格\n"+
"2.不合法算式的错误提示\n"+
"3.运算精度到小数点后8位\n"+
"4.支持键盘输入,屏蔽了大多数无关键,可放心食用\n\n"+
"不足:\n"+
"1.键盘输入时按钮没有被点击效果\n"+
"2.超出显示屏宽度时显示不了后面的内容\n"+
"3.点击过按钮之后按回车键会再次触发按钮\n\n"+
"PS: 比如当你看完这段readme点完确定之后,再按回车键就会再次弹出readme,需点其他非按钮处才能破除,请先点击非按钮处再尝试键盘输入\n");
}
function showError(message) {
alert("'"+document.getElementById("output").value+"'"+"不是合法算式");
clean();
}
function getCommand(num){
if (num == '=') updateoutput();
else if (num == "CE") clean();
else if (num == '←') back();
else document.getElementById("output").value += document.getElementById(num).value;
}
function updateoutput() {
if (document.getElementById("output").value == " ") return;
if (judgeLegal() == true) {
try {
document.getElementById("output").value = parseFloat(eval(document.getElementById("output").value).toFixed(8));
}
catch (SyntaxError) {
showError(document.getElementById("output").value);
}
}
else {
showError(document.getElementById("output").value);
}
}
function clean() {
document.getElementById("output").value = "";
}
function back() {
var str = document.getElementById("output");
if (str.value == 0 || str.value.length == 1) str.value = " ";
else str.value = str.value.substring(0, str.value.length - 1);
}
function judgeLegal() {
var str = document.getElementById("output").value;
for (var index = 0; index < str.length; index++) {
if (index == 0) {
if (str[index] == '+'|| str[index] == '/'|| str[index] == '*') return false;
}
if ((str[index] == '+'|| str[index] == '-'|| str[index] == '/'|| str[index] == '*')&&
(str[index+1] == '+'|| str[index+1] == '-'|| str[index+1] == '/'|| str[index+1] == '*')) {
return false;
}
if (str[index] == '.' && (str[index+1] == '.'|| str[index+1] == '+'|| str[index+1] == '-'||
str[index+1] == '*'|| str[index+1] == '/')) return false;
if (str[index] == '/' && str[index+1] == '0') return false;
}
return true;
}
拓展功能:
键盘输入,但点击过页面中按键之后再回车键会锁定输入该按键的内容,需点击非按键处才能回复enter键的“=”功能;目前不知道怎么解决。
待实现:
显示内容超出显示屏时字体自动变更大小,思路是默认设置字体为一定大小(恰好符合边框),当内容超出边框时,减小字号再与边框大小进行比较,若还是超出边框,继续缩小字体,直到字体缩小后小于边框。
计算历史记录:
每次运算都新建变量存储,用单独的区域显示计算历史