Create a Counter in JavaScript in Five Steps

JavaScript 五个步骤制作计数器

前言

解题

第一步:制作界面

先定义一个 counter 区块,里面有显示目前数字与装载三个按钮的容器buttonGroup,其内容包含「减、归零、加」等按钮。

<div class="counter">
<div id="counterDisplay" class="counter__display"></div>
<div id="buttonGroup" class="buttonGroup">
<button class="button" id="minus">-</button>
<button class="button" id="reset">Reset</button>
<button class="button" id="add">+</button>
</div>
</div>

第二步:选择画面元素

使用前面定义好的 id 属性来选择各个 DOM 元素(使用 getElementById🔗 方法),并且储存于变量中。

// 选择画面元素
const counterDisplay = document.getElementById('counterDisplay');
const counterMinusButton = document.getElementById('minus');
const counterResetButton = document.getElementById('reset');
const counterAddButton = document.getElementById('add');
const counterButtons = document.getElementById('buttonGroup');

第三步:将数据打印到画面上

目前画面中 counterDisplay 内是没有任何内容的,所以可以先定义好一笔数据再把该数据渲染到画面中;由于「渲染数据到画面中」是重复性极高的动作,可以将其独立为一个函数之后有需要时再调用。

const counter = 0;
function renderCounter() {
counterDisplay.textContent = counter;
}
renderCounter(counter);

第四步:监听事件

目前数据已经可以正确的显示在画面上,但是按钮还没有任何功能,所以接下来要做的就是监听按钮的点击事件,并且在点击时执行对应的函数;使用 eventListener🔗 监听「点击」事件。

// 当点击 + 按钮,执行 addCounter() 函数
counterAddButton.addEventListener('click', (e) => {
addCounter();
});
// 当点击 Reset 按钮,执行 resetCounter() 函数
counterResetButton.addEventListener('click', (e) => {
resetCounter();
});
// 当点击 - 按钮,执行 subtractCounter() 函数
counterMinusButton.addEventListener('click', (e) => {
subtractCounter();
});

换句话说,也可以用一个 eventListener 达成 3 个 eventListener 所做的事,只要检查其容器点击时,被点击的事件的对象的 id (e.target.id) 名称是什么并比对做出对应的行为即可。

counterButtons.addEventListener('click', (e) => {
if (e.target.id === 'add') {
addCounter();
} else if (e.target.id === 'reset') {
resetCounter();
} else if (e.target.id === 'minus') {
subtractCounter();
}
});

第五步:操纵数据

接下来就是要实现各个按钮的功能,这边先定义好三个函数,分别是「加、减、重置」。

// 增加 counter 的值并重新渲染画面
function addCounter() {
counter++;
renderCounter(counter);
}
// 重置 counter 的值并重新渲染画面
function resetCounter() {
counter = 0;
renderCounter(counter);
}
// 减少 counter 的值并重新渲染画面
function subtractCounter() {
counter--;
renderCounter(counter);
}

结语

从这个简单的练习中,我们分离了数据与逻辑,这样的切割方式可以更容易的维护代码,也可以让其他开发者更容易阅读与改动。

这是一个简单的范例,但背后可以思考与改善的事情仍然很多,像是:如何让程序「可以被重复利用?」、「如何让程序可被预测与测试?」……等,这些问题都是值得思考的。

See the Pen Counter by Riceball ( @riecball) on CodePen.