티스토리 뷰

반응형

 

웹 개발을 하다 보면 사용자 입력값에 따라 다른 값을 동적으로 계산해야 하는 상황이 자주 발생합니다. 예를 들어, 철판 수량과 무게를 계산하는 경우, 사용자가 수량을 입력하면 무게를 자동으로 계산해주고, 반대로 무게를 입력하면 수량을 계산해주는 기능이 필요할 수 있습니다.

이때, 두 입력 필드 간 값이 서로 변환되도록 코드를 작성하다 보면 의도치 않게 무한 루프에 빠지는 경우가 발생할 수 있습니다. 이 글에서는 이런 무한 루프 문제를 방지하면서도 깔끔하게 값을 동적으로 변환하는 방법을 소개합니다.

수량, 톤을 서로 입력하면 변환해 주는 내용, 실전 프로그램 적용


 

두 입력 필드 간 값 변환의 어려움

웹 폼에서 두 입력 필드 간 값을 변환할 때의 문제는 간단합니다.

  1. A 입력 필드에 값이 입력되면 B 필드가 업데이트됩니다.
  2. 반대로 B 필드에 값이 입력되면 A 필드가 다시 업데이트됩니다.

이 과정이 반복되면 브라우저는 끝없이 A와 B 필드를 갱신하려고 시도하게 되며, 이는 결국 무한 루프를 야기합니다. 이 문제를 해결하기 위해 우리는 간단한 "플래그 변수"를 활용합니다.


무한 루프 방지 기법: 플래그 변수

플래그 변수는 특정 동작이 실행 중인지 여부를 나타내는 변수입니다. 여기서 isCalculating이라는 플래그를 사용해 현재 계산이 진행 중인 상태를 추적합니다.

만약 한 입력 필드가 값을 갱신하는 중이라면 플래그를 활성화(true) 시켜 다른 필드의 계산 이벤트가 트리거되지 않도록 합니다. 계산이 끝나면 플래그를 비활성화(false)로 설정해 다른 이벤트가 정상적으로 작동할 수 있도록 합니다.

이 기법을 활용하면 아래와 같은 구조로 코드를 작성할 수 있습니다.


코드 설명

HTML 구조

먼저, 두 개의 입력 필드가 있다고 가정합니다.

<input type="text" id="steelnum" placeholder="수량">
<input type="text" id="tonweight" placeholder="무게(톤)">

JavaScript로 값 변환 구현

아래는 JavaScript로 steelnum과 tonweight 필드 간 값을 동적으로 변환하는 코드입니다.

$(document).ready(function () {
  // 단위 무게 계산 함수
  function calculateUnit() {
    var spec = $('#spec').val();
    if (!spec) {
      alert('규격(spec)를 입력해주세요.');
      return null;
    }
    var arr = spec.split('*');
    if (arr.length !== 3) {
      alert('규격 형식이 올바르지 않습니다. 예: 1.2*1219*2438');
      return null;
    }
    var length = parseFloat(arr[0]);
    var width = parseFloat(arr[1]);
    var height = parseFloat(arr[2]);

    if (isNaN(length) || isNaN(width) || isNaN(height)) {
      alert('규격에 포함된 길이, 너비, 높이가 숫자가 아닙니다.');
      return null;
    }

    // 단위 무게 계산 (kg)
    var unit = (length * width * height * 7.93) / 1000000;
    return unit; // kg
  }

  // 플래그 변수
  var isCalculating = false;

  // steelnum 입력 시 tonweight 계산
  $('#steelnum').on('input', function () {
    if (isCalculating) return; // 계산 중이면 실행하지 않음
    var steelnum = parseFloat($(this).val());
    if (isNaN(steelnum) || steelnum <= 0) {
      $('#tonweight').val('');
      return;
    }

    var unit = calculateUnit();
    if (unit === null) return;

    isCalculating = true; // 플래그 활성화
    var tonweight = (steelnum * unit) / 1000; // 무게 계산
    $('#tonweight').val(tonweight.toFixed(3)); // 결과 표시
    isCalculating = false; // 플래그 비활성화
  });

  // tonweight 입력 시 steelnum 계산
  $('#tonweight').on('input', function () {
    if (isCalculating) return; // 계산 중이면 실행하지 않음
    var tonweight = parseFloat($(this).val());
    if (isNaN(tonweight) || tonweight <= 0) {
      $('#steelnum').val('');
      return;
    }

    var unit = calculateUnit();
    if (unit === null) return;

    isCalculating = true; // 플래그 활성화
    var steelnum = (tonweight * 1000) / unit; // 수량 계산
    $('#steelnum').val(Math.round(steelnum)); // 결과 표시
    isCalculating = false; // 플래그 비활성화
  });
});

코드 흐름 이해하기

위 코드에서 중요한 부분은 플래그(isCalculating)를 사용해 계산이 진행 중일 때 다른 이벤트가 실행되지 않도록 차단하는 것입니다.

  • steelnum 입력 시:
    1. 입력값을 가져옵니다.
    2. 단위 무게를 계산합니다.
    3. tonweight 필드 값을 계산하고 업데이트합니다.
  • tonweight 입력 시:
    1. 입력값을 가져옵니다.
    2. 단위 무게를 계산합니다.
    3. steelnum 필드 값을 계산하고 업데이트합니다.

두 입력 필드가 서로 값을 갱신할 때, 플래그가 활성화된 동안에는 다른 이벤트가 차단되므로 무한 루프가 발생하지 않습니다.


활용 사례

이 기법은 두 입력 필드뿐만 아니라 더 복잡한 상황에서도 응용할 수 있습니다. 예를 들어, 환율 계산기, 상품 가격과 할인율 계산, 또는 온도 변환기 등 다양한 동적 계산 기능에 사용할 수 있습니다.

이와 같은 구조를 활용하면 사용자 경험을 향상시키는 동적 기능을 구현하면서도 예기치 않은 오류를 방지할 수 있습니다.


이처럼 간단한 플래그 변수를 활용하는 것만으로도 무한 루프 문제를 쉽게 해결할 수 있습니다. 이 기법은 작은 차이로 큰 문제를 예방하는 개발 노하우라 할 수 있습니다. 앞으로 비슷한 상황에서 활용해 보시길 바랍니다.

반응형
댓글