我定义了function plusOne()
,它应该为变量添加+1(然后将元素的innerHTML
设置为该变量)。单击button
时会调用该函数。
但是,+1的添加仅适用一次。每次单击按钮时,如何更改我的功能以便为变量添加+1?
这里是我的函数和HTML现在的样子,以及JSFiddle:
function plusOne() {
var number = 1;
var count = document.getElementById('count');
number++;
count.innerHTML = number;
}

<div>
<span id="count">1</span>
</div>
<div>
<button onclick="plusOne()">
+
</button>
</div>
&#13;
链接到JSFiddle:https://jsfiddle.net/johschmoll/hLymhak7/1/
答案 0 :(得分:2)
更改JavaScript以将number
变量放在点击处理程序之外。否则,每次调用单击处理程序时,您都会将number
变量重置为1.
var number = 1;
function plusOne() {
var count = document.getElementById('count');
number++;
count.innerHTML = number;
}
示例:https://jsfiddle.net/hLymhak7/6/
如果元素永远不会被销毁,那么将元素引用保留在click处理程序的范围之外也是一个好主意。
var number = 1;
var count = document.getElementById('count');
function plusOne() {
number++;
count.innerHTML = number;
}
DOM查询查询现在很便宜,但其中很多都会对应用程序的性能产生负面影响。
示例:https://jsfiddle.net/hLymhak7/8/
我们甚至可以将count
元素传递给点击处理程序,以便更容易测试。
var number = 1;
function plusOne(count) {
number++;
count.innerHTML = number;
}
<div>
<span id="count">1</span>
</div>
<div>
<button onclick="plusOne(count)">
+
</button>
</div>
span
元素实际上分配给一个全局变量,该变量在button
元素的范围内,就像plusOne
点击处理程序一样。这意味着在所有示例中,我们都可以轻松地使用count
或window.count
来访问span
元素。
示例:https://jsfiddle.net/hLymhak7/12/
建议不要使用onclick
元素的button
属性绑定点击处理程序。其中一个原因是我们只允许添加一个onclick
处理程序,而Element#addEventListener
则不然。
<div>
<span id="count">1</span>
</div>
<div>
<button id="incrementor">
+
</button>
</div>
var number = 1;
var count = document.getElementById('count');
var incrementor = document.getElementById('incrementor');
incrementor.addEventListener('click', plusOne);
function plusOne() {
number++;
count.innerHTML = number;
}
See more discussions about onclick
示例:https://jsfiddle.net/hLymhak7/13/
我们可以添加一个单击侦听器,它也会将count
元素显式传递给plusOne
函数。
var number = 1;
var count = document.getElementById('count');
var incrementor = document.getElementById('incrementor');
incrementor.addEventListener('click', function onClick() {
plusOne(count);
});
function plusOne(count) {
number++;
count.innerHTML = number;
}
现在,我们距离易于测试的可维护代码更近了一步。
示例:https://jsfiddle.net/hLymhak7/14/
我们可以通过明确第二个依赖项来完成我们的解决方案,即number
状态变量。
当我们将此变量传递给plusOne
函数时,我们现在有一个pure function,可以轻松测试和推理。
<div>
<span id="count">1</span>
</div>
<div>
<button id="incrementor">
+
</button>
</div>
var number = 1;
var count = document.getElementById('count');
var incrementor = document.getElementById('incrementor');
incrementor.addEventListener('click', function onClick() {
number = plusOne(count, number);
});
function plusOne(count, number) {
number++;
count.innerHTML = number;
return number;
}
虽然这更详细,但依赖关系是明确的,实际的业务逻辑,即plusOne
函数,可以提取到一个单独的文件,并进行单元测试,以验证它是否符合预期。< / p>
import { plusOne } from './plus-one';
describe('plusOne', () => {
let countElement;
let initialState;
let state;
beforeEach(() => {
initialState = 1;
state = initialState;
countElement = {
innerHTML: initialState.toString(),
};
})
it('returns an incremented state', () => {
state = plusOne(countElement, state);
expect(state).toBe(initialState + 1);
});
it('does not mutate the state', () => {
plusOne(countElement, state);
expect(state).toBe(initialState);
})
it('reflects the state in the count element', () => {
state = plusOne(countElement, state);
expect(countElement.innerHTML).toEqual(state);
});
});
示例:https://jsfiddle.net/hLymhak7/15/
很多网络应用都将状态保留在DOM中。虽然这很简单,但我们的代码中的可变状态较少,但通常我们希望在应用程序的多个位置访问状态。
必须在我们需要的所有地方从DOM中提取状态不是它应该如何。我们应该将我们的业务逻辑保留在JavaScript中,让DOM反映状态,而不是反过来。
它还增加了与DOM的紧密耦合,使其更难以维护和测试。
// Keeping state in DOM is NOT recommended, but here we go...
var count = document.getElementById('count');
function plusOne() {
var number = Number(count.innerHTML);
number++;
count.innerHTML = number.toString();
}
答案 1 :(得分:1)
<!-- Using inline js-->
<div>
<span id="count">1</span>
</div>
<div>
<button onclick="document.getElementById('count').innerHTML++">
+
</button>
</div>
答案 2 :(得分:0)
function plusOne(){
var count = document.getElementById('count');
count.innerHTML++
}
&#13;
<div>
<span id="count">1</span>
</div>
<div>
<button onclick="plusOne()">
+
</button>
</div>
&#13;