如何在按钮点击时重复向变量添加+1?

时间:2018-01-24 09:24:23

标签: javascript jquery html css

我定义了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;
&#13;
&#13;

链接到JSFiddle:https://jsfiddle.net/johschmoll/hLymhak7/1/

3 个答案:

答案 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元素传递给点击处理程序,以便更容易测试。

的JavaScript

var number = 1;

function plusOne(count) {
  number++;
  count.innerHTML = number;
}

HTML

<div>
  <span id="count">1</span>
</div>

<div>
  <button onclick="plusOne(count)">
    +
  </button>
</div>

span元素实际上分配给一个全局变量,该变量在button元素的范围内,就像plusOne点击处理程序一样。这意味着在所有示例中,我们都可以轻松地使用countwindow.count来访问span元素。

示例:https://jsfiddle.net/hLymhak7/12/

最佳实践:添加为事件侦听器

建议不要使用onclick元素的button属性绑定点击处理程序。其中一个原因是我们只允许添加一个onclick处理程序,而Element#addEventListener则不然。

HTML

<div>
  <span id="count">1</span>
</div>

<div>
  <button id="incrementor">
    +
  </button>
</div>

的JavaScript

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,可以轻松测试和推理。

HTML

<div>
  <span id="count">1</span>
</div>

<div>
  <button id="incrementor">
    +
  </button>
</div>

的JavaScript

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/

测试套件示例:https://stackblitz.com/edit/stack-overflow-javascript-jquery-repeatedly-add-1-to-variable-o?file=src%2Fplus-one.spec.ts

反模式:在DOM中保持状态

很多网络应用都将状态保留在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();
}

示例:https://jsfiddle.net/hLymhak7/9/

答案 1 :(得分:1)

<!-- Using inline js-->
<div>
  <span id="count">1</span>
</div>

<div>
  <button onclick="document.getElementById('count').innerHTML++">
    +
  </button>
</div>

答案 2 :(得分:0)

&#13;
&#13;
function plusOne(){
var count = document.getElementById('count');
count.innerHTML++
}
&#13;
<div>
  <span id="count">1</span>
</div>

<div>
  <button onclick="plusOne()">
    +
  </button>
</div>
&#13;
&#13;
&#13;