>

function plusOne() 를 정의했습니다  변수에 +1을 더한 다음 innerHTML 를 설정해야합니다.  해당 변수가 될 요소). 함수가 button 일 때 호출됩니다.  클릭됩니다.

그러나 +1을 추가하면 한 번만 작동합니다. 버튼을 클릭 할 때마다 변수에 +1을 추가하려면 함수를 어떻게 변경해야합니까?

다음은 JSFiddle과 함께 내 함수와 HTML이 어떻게 보이는지 보여줍니다.

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>

JSFiddle에 연결 : https://jsfiddle.net/johschmoll/hLymhak7/1/

  • 답변 # 1

    최소 솔루션 : 상태 변수를 클릭 핸들러 범위 밖으로 이동 number 를 넣어 자바 스크립트를 변경  클릭 핸들러 외부의 변수 그렇지 않으면, 당신은 number 를 재설정  클릭 핸들러가 호출 될 때마다 1로 변경됩니다.

    var number = 1;
    function plusOne() {
      var count = document.getElementById('count');
      number++;
      count.innerHTML = number;
    }
    
    

    예 : https://jsfiddle.net/hLymhak7/6/

    요소 참조를 클릭 핸들러 범위 밖으로 이동

    요소가 절대로 파괴되지 않으면 요소 참조를 클릭 핸들러 범위 밖으로 유지하는 것이 좋습니다.

    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;
    }
    
    

    HTML

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

    와이즈 비즈  요소는 실제로 span 범위 내에있는 전역 변수에 지정됩니다.  Wyzwyz와 같은 요소  클릭 핸들러. 이것은 모든 예에서 button 를 쉽게 사용할 수 있음을 의미합니다.  또는 plusOne   count 에 액세스  요소.

    예 : https://jsfiddle.net/hLymhak7/12/

    모범 사례 : 이벤트 리스너로 추가

    window.count 를 사용하여 클릭 핸들러를 바인딩하지 않는 것이 좋습니다.   span 의 속성  요소. 그 이유 중 하나는 우리가 오직 하나의 onclick 를 추가 할 수 있다는 것입니다.  핸들러 ( button 의 경우는 아님) .

    HTML

    onclick
    
    

    자바 스크립트

    Element#addEventListener
    
    

    onclick에 대한 추가 토론보기

    예 : https://jsfiddle.net/hLymhak7/13/

    명시적인 요소 의존성을 가진 모범 사례 결합

    <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; } 에 명시 적으로 요소  기능.

    count
    
    

    이제 쉽게 테스트 할 수있는 유지 보수 가능한 코드에 한 걸음 더 다가 섰습니다.

    예 : https://jsfiddle.net/hLymhak7/14/

    유지 보수가 용이하고 쉽게 테스트 할 수있는 최종 솔루션

    두 번째 종속성, 즉 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; } 에 전달할 때  함수, 이제 테스트하고 추론하기 쉬운 순수한 함수를 갖습니다.

    HTML

    number
    
    

    자바 스크립트

    plusOne
    
    

    이것이 더 장황하지만, 의존성이 명확하고 실제 비즈니스 로직, 즉 <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;
    }
    
    

    예 : 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에 긴밀하게 연결되어 유지 관리 및 테스트가 더 어려워집니다.

    plusOne
    
    

    예 : https://jsfiddle.net/hLymhak7/9/

  • 답변 # 2

    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);
      });
    });
    
    

  • 답변 # 3

    // 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();
    }
    
    

    <!-- Using inline js-->
    <div>
      <span id="count">1</span>
    </div>
    <div>
      <button onclick="document.getElementById('count').innerHTML++">
        +
      </button>
    </div>
    
    

    function plusOne(){ var count = document.getElementById('count'); count.innerHTML++ }

관련 자료

  • 이전 vuejs2 - axios로 api rest 호출을하기 위해 nuxt에 헤더 추가
  • 다음 php - 라 라벨 페이지 매김 페이지 번호 추가