为什么要自己做计算器?
你可能会说,手机自带计算器,为什么还要自己做?原因很简单——学编程最好的方式就是做一个有用的小工具。计算器虽然简单,但涉及到页面布局、事件处理、逻辑运算,是非常好的练手项目。
而且我们的计算器有个特别功能:历史记录。每次计算的结果都会保存下来,方便你对账或者回顾。
第一步:画出计算器的样子
创建 index.html:
计算历史
我们用了 CSS Grid 布局来排列按钮,它就像一个网格,把按钮整整齐齐地放在4列里。
第二步:用JavaScript生成按钮
var keys = [
"7","8","9","/",
"4","5","6","*",
"1","2","3","-",
"0",".","=","+"
];
var btns = document.getElementById("buttons");
for (var i = 0; i < keys.length; i++) {
var btn = document.createElement("button");
btn.textContent = keys[i];
if (keys[i] === "=") btn.className = "eq";
else if ("+-*/".indexOf(keys[i]) > -1) btn.className = "op";
else btn.className = "num";
btns.appendChild(btn);
}
第三步:实现计算逻辑
var expression = "";
var display = document.getElementById("display");
btns.addEventListener("click", function(e) {
if (e.target.tagName !== "BUTTON") return;
var key = e.target.textContent;
if (key === "=") {
try {
var result = Function("return " + expression)();
addHistory(expression + " = " + result);
display.textContent = result;
expression = String(result);
} catch(err) {
display.textContent = "错误";
expression = "";
}
} else {
expression += key;
display.textContent = expression;
}
});
这里用了事件委托技巧:不是给每个按钮单独绑事件,而是在父元素上监听,通过判断点击的是哪个按钮来处理。就像一个前台接待员,谁来了都由她分配。
第四步:加上历史记录
var historyList = document.getElementById("historyList");
function addHistory(text) {
var li = document.createElement("li");
li.textContent = text;
historyList.insertBefore(li, historyList.firstChild);
// 保存到本地存储
var history = JSON.parse(
localStorage.getItem("calc-history") || "[]"
);
history.unshift(text);
if (history.length > 20) history = history.slice(0, 20);
localStorage.setItem("calc-history", JSON.stringify(history));
}
最多保存20条记录,防止存太多。
可以继续加的功能
一个有模有样的计算器就完成了。不到100行代码,你就拥有了一个带历史记录的专属计算器。