首先进行一个简单的布局,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>计算器</title>
<style>
*{
margin: 0;
padding: 0;
}
table {
width: 320px;
border-collapse: 0;
border: 1px solid#000;
margin: 0 auto;
background-color: skyblue;
}
tr>td {
width: 100%;
}
tr>td>button {
width: 100%;
height: 50px;
font-size: 20px;
}
#scipt {
position: relative;
width: 318px;
height: 200px;
border: 1px solid #000;
background-color: #ccc;
border-style: border-box;
}
#num {
position: absolute;
bottom: 2px;
right: 0px;
padding: 0 5px 0 20px;
font-size: 60px;
letter-spacing: 2px;
}
#eval {
position: absolute;
top: 2px;
right: 0px;
padding: 0 5px 0 20px;
color: #606060;
font-size: 30px;
}
#Equals {
background-color: rgba(192,192,192.6);
}
.maxW {
font-size: 20px !important;
}
</style>
</head>
<body>
<table class="tab">
<tr>
<td colspan="5">
<div id="scipt">
<div id="num">0</div>
<div id="eval"></div>
</div>
</td>
</tr>
<tr>
<td><button class="btn">1/x</button></td>
<td><button class="btn">C</button></td>
<td><button class="btn">del</button></td>
<td><button class="btn">/</button></td>
</tr>
<tr>
<td><button class="btn">7</button></td>
<td><button class="btn">8</button></td>
<td><button class="btn">9</button></td>
<td><button class="btn">*</button></td>
</tr>
<tr>
<td><button class="btn">4</button></td>
<td><button class="btn">5</button></td>
<td><button class="btn">6</button></td>
<td><button class="btn">-</button></td>
</tr>
<tr>
<td><button class="btn">1</button></td>
<td><button class="btn">2</button></td>
<td><button class="btn">3</button></td>
<td><button class="btn">+</button></td>
</tr>
<tr>
<td><button class="btn" >±</button></td>
<td><button class="btn">0</button></td>
<td><button class="btn">.</button></td>
<td><button class="btn" id="Equals" >=</button></td>
</tr>
</table>
</body>
</html>
引入外部script文件
<script src="js/Calculator.js"></script>
//外部的js脚本 注意 元素是否初始化的问题
//代码要写到网页加载完成之后
/*
网页加载完成事件
*/
var btnlist = null;//记录所有按钮
var userkeep = 0;//记录用户的按键值
var screenNum = null;//记录屏幕显示数字的
var screen = null; //记录整个显示屏
var result = [];
var Eval = null;//记录显示表达式的元素
var Symbol = false;//记录用户是否按过符号 false是没按过,true是按过
var save = null;
window.onload = function(){
/*
1.给所有的计算器添加事件
*/
btnlist = document.getElementsByClassName("btn");
screenNum = document.getElementById("num");
screen = document.getElementById("scipt");
Eval = document.getElementById("eval");
for(var i = 0;i<btnlist.length;i++)
{
btnlist[i].onclick = function()
{
// console.log(this.innertext);
// 检测当前按钮是不是数字按钮
//isNaN 是检测是否是非数字 true非数字 false 数字
if(!isNaN(this.innerText)||this.innerText ==".")
{
console.log(this.innerText);
//调用方式 检测屏幕是否满页
//checkScreen 带返回值的方法 可以输入返回 true 否则返回 flase
if(checkScreen()){
//检测用户有没有按过符号
if(Symbol){
userkeep = null;
Symbol = false;
}//true 用户按过符号
if (userkeep)
{
//检测当前用户输入的是否有.
//使用indexOf 检测字符串,如果有返回字符串,如果没有就返回-1
if(userkeep.indexOf(".")!=-1){
//里面有.
if(this.innerText!="."){
userkeep += this.innerText;//字符串拼接
}
}
else {
//没有.
userkeep = this.innerText;//字符串拼接
}
}
else {
if(this.innerText=="."){
userkeep = "0"+this.innerText;//如果直接输入了·那么,屏幕上出现0.
}
else {
userkeep = this.innerText;//字符串拼接
}
}
screenNum.innerText = userkeep;
}
}
else
{
console.log("非数字");
switch (this.innerText){
case "+":saveResult("+"); break;
case "-":saveResult("-"); break;
case "*":saveResult("*"); break;
case "/":saveResult("/"); break;
case "=":
//计算表达式
//将最后一次屏幕值添加到数组
//result[result.length] = userkeep;
//eval 方法可以直接计算表达式
console.log(result);
//result[result.length - 1] 数组的最后一位不是符号而是1/x 取它的前一位
var F = null;
if (!isNaN(result[result.length - 1])) {
userkeep = eval(result.join(""));
}
else {
F = result[result.length - 1].indexOf("reciproc") != -1 ? result[result.length - 2] : result[result.length - 1];
userkeep = eval(save + F + userkeep);
}
screenNum.innerText = userkeep;
Eval.innerText = "";
result = [];
break;
// console.log(eval); break;//计算表达式
//清除功能
case "C":
screenNum.innerText = 0;
Eval.innerText = "";
userkeep = null;
result = [];
Symbol = false;
save = null;
break;
case "del":
//删除键
//使用的是字符串的截取方法
//substr substring
//substr 参数 strat length 该方法的返回值是截取的字符 原字符串不受影响
//substring 参数 start end 取小不取大 0 2 原字符串不受影响
userkeep = userkeep.length - 1 > 0 ? userkeep.substr(0, userkeep.length - 1) : 0;
screenNum.innerText = userkeep;
break;
case "1/x":
//按该键的时候当前用户输入的值 计算1/x
//存入数组
result[result.length] = "reciproc("+userkeep+")"
userkeep = 1/userkeep;
console.log(userkeep);
Eval.innerText = result.join("");
screenNum.innerText = userkeep;
console.log(result);
break;
case "±":
//按键 用户输入的值 正负切换
if (userkeep < 0) {
userkeep = -userkeep;
}
else if (userkeep > 0) {
userkeep = "-" + userkeep;
}
screenNum.innerText = userkeep;
break;
case "%":
// 问题严重???
if (ishasF) {
result[result.length - 1] = ((save * userkeep) / 100).toString();
}
else {
result[result.length] = ((save * userkeep) / 100).toString();
}
userkeep = (save * userkeep) / 100;
screenNum.innerText = userkeep;
Eval.innerText = result.join("");
Symbol = true;
break;
}
}
}
}
//手动回收,防止内存泄漏
btnlist = null;
}
function checkScreen(){
//parseFloat() 将字符串类型的数字转换为数字带小数点
// parseInt() 将字符串类型转换为整数
//可以去掉字符 前提是 数字在前 字符在后
var w = parseFloat(window.getComputedStyle(screenNum).width);
var scw = parseFloat(window.getComputedStyle(screen).width);
//检测是否变小
if(screenNum.classList.contains("maxW")&&w+40>=scw){
return false;
}
if (w+40>=scw) {
screenNum.classList.add("maxW")
}
return true;
}
/*
记录表达式
text 符号
result存储按键和符号
*/
function saveResult(text){
if(Symbol){
//这里是再一次按符号
//直接修改数组里面的最后一位 为当前符号
result[result.length-1] = text;
}
else{
//存入屏幕的值
result[result.length] = userkeep.toString();//将数字类型转化为字符串
//不加下面的代码 是按照表达式里面优先级运算进行的
//在点击符号的时候先计算之前值
save = eval(filterRes("calculation"));
//calculation 代表计算
screenNum.innerText = eval(result.join(""));
//存入符号
result[result.length] = text;
}
// 显示到屏幕上
//result.join("") join方法是将数组里面的每一位 用空字符拼接
//显示到屏幕上
// console.log(text,userkeep);
//下面map 是映射将数组映射成一个新的数组
//下面代码知道功能就行
result = result.map(function(value,index){
if(isNaN(value)) {
return "" +value +"";
}
else {
return value;
}
})
Eval.innerText = filterRes("expression").join("") ;
Symbol = true;//修改状态
}
/*
实现过滤 reciproc
表达式显示需要reciproc 计算的时候不需要reciproc
*/
function filterRes(){
var filter = null;
if(way == "calculation"){
//计算方式过滤
filter = result.map(function(vaule,index){
if(vaule.indexOf("reciproc")==-1){
return vaule;
}
else {
return "";
}
});
}
else{
//表达式显示过滤
var reciindex = null;
filter = result.map(function(vaule,index){
if(vaule.indexOf("reciproc")!==-1){
reciindex = index;
return vaule;
}
if(reciindex!=null&&reciindex+1==index){
vaule = "";
}
return value;
});
reciindex = "";
}
return filter;
}