스크롤 시 숫자카운팅 질문

매출이 오르면 내리는 수수료! 지금 수수료센터에서 전자결제(PG)수수료 비교견적 신청해 보세요!
스크롤 시 숫자카운팅 질문

QA

스크롤 시 숫자카운팅 질문

본문


 
  <!-- 숫자 인덱스     -->
    <div class="num-container" id="num-container">
      
        <div class="num-item">
            <!--<h4 class="in-title">Index 2</h4>-->
            <span class="nums" data-count="24743">1000</span><span id="num-unit">건</span><br>
            <!--<span class="sub-title">프랜차이즈 매장수</span><br>-->
        </div>
    
    </div>
<style>
        .upper_blank {
            height: 300px;
            background: yellowgreen;
            text-align: center;
            padding-top: 200px;
        }
        .num-container {
            display: flex;
            flex-wrap: wrap;
          
            align-items: center;
            justify-content: flex-start;
        }
        .num-item {
            text-align: center;
           padding-top: 23%;
          
       
          width: 300px;
             height: 300px;
        }
        .in-title {
            font: 30px/1 'arial';
            color: gray;
            font-weight: 600;
            margin-bottom: 20px;
        }
        .sub-title {
            font: 14px/1 'arial';
            color: gray;
        }
        .nums {
            font: bold 60px/1 'arial';
            color: gray;
        }
        #num-unit {
            font: bold 25px/1 'arial';
            color: gray;
        }
    </style>
 
    <script>
      
      $(window).scroll(function() {
        //숫자 카운트 애니메이션
        $('.nums').each(function () {
            const $this = $(this),
                countTo = $this.attr('data-count');
            $({
                countNum: $this.text()
            }).animate({
                countNum: countTo
            }, {
                duration: 3000,
                easing: 'linear',
                step: function () {
                    $this.text(Math.floor(this.countNum));
                },
                complete: function () {
                    $this.text(this.countNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
                    //3자리 마다 콤마 표시 적용
                }
            });
        });
      
      });
    </script>

   
 
  

 

숫자 카운팅까지는 구현했는데 스크롤을 움직이기만 하면 숫자가 카운팅이 됩니다.

해당 부분에 도착했을 때 숫자가 카운팅 되게 하려면 어떻게 해야 할까요?

 

 

 

이 질문에 댓글 쓰기 :

답변 4

다음과 같이 하시면 가능하지 않을까 합니다.


<script>
  $(window).scroll(function() {
    // .num-container가 화면에 보일 때 숫자 카운팅 시작
    if (isElementInViewport('.num-container')) {
      //숫자 카운트 애니메이션
      $('.nums').each(function () {
          const $this = $(this),
              countTo = $this.attr('data-count');
          $({
              countNum: $this.text()
          }).animate({
              countNum: countTo
          }, {
              duration: 3000,
              easing: 'linear',
              step: function () {
                  $this.text(Math.floor(this.countNum));
              },
              complete: function () {
                  $this.text(this.countNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
                  //3자리 마다 콤마 표시 적용
              }
          });
      });
    }
  });
  // 특정 요소가 화면에 보이는지 여부를 확인하는 함수
  function isElementInViewport(el) {
    var rect = $(el)[0].getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }
</script>

다음과 같이 수정해 보시겠어요


<script>
  var counted = false; // 한 번만 카운팅되도록 변수 추가

  $(window).scroll(function() {
    // .num-container가 화면에 보이고 아직 카운팅이 안된 경우에만 숫자 카운팅 시작
    if (!counted && isElementInViewport('.num-container')) {
      counted = true; // 카운팅 플래그를 true로 설정하여 한 번만 실행되도록 함

      //숫자 카운트 애니메이션
      $('.nums').each(function () {
          const $this = $(this),
              countTo = $this.attr('data-count');
          $({
              countNum: $this.text()
          }).animate({
              countNum: countTo
          }, {
              duration: 3000,
              easing: 'linear',
              step: function () {
                  $this.text(Math.floor(this.countNum));
              },
              complete: function () {
                  $this.text(this.countNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
                  //3자리 마다 콤마 표시 적용
              }
          });
      });
    }
  });

  // 특정 요소가 화면에 보이는지 여부를 확인하는 함수
  function isElementInViewport(el) {
    var rect = $(el)[0].getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }
</script>

해결해 주셔서 너무 감사했습니다... 근데 혹시 혹시 모바일로 가면 코드가 달라지는 부분이 있을까요,,? 모바일로 가니깐 도착하기 전에 이미 카운팅 이벤트가 끝나버려서요,,,,,,

모바일에서 안된다면 전체를 $(document).ready(function() { ..기존 코드 }); 로 감싸보세요.

 

모바일 디바이스에서는 일반적으로 화면 크기가 작아지고, 스크롤 이벤트 처리 방식이 다를 수 있으므로 구현 하는 방법에 따라 차이가 있을 수는 있을 것 같습니다.

다음을 참고 하셔서 원하시는 형식으로 구현 하시면 가능하지 않을까 합니다.

 

반응형일 경우 CSS를 추가 하셔야 할 수도 있을 것 같네요

모바일 관련 구현 방식


<script>
  var countedMap = {}; // 각 .nums 요소에 대한 카운팅 상태를 관리하는 맵
  $(window).on('scroll load resize', function() {
    // .num-container가 화면에 보이고 아직 카운팅이 안된 경우에만 숫자 카운팅 시작
    $('.nums').each(function () {
      var $this = $(this);
      if (!countedMap[$this.attr('data-count-id')] && isElementInViewport($this)) {
        countedMap[$this.attr('data-count-id')] = true; // 해당 요소의 카운팅 플래그를 true로 설정하여 더 이상 진행되지 않도록 함
        // 숫자 카운트 애니메이션
        $({
          countNum: $this.text()
        }).animate({
          countNum: $this.attr('data-count')
        }, {
          duration: 3000,
          easing: 'linear',
          step: function () {
            $this.text(Math.floor(this.countNum));
          },
          complete: function () {
            $this.text(this.countNum.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','));
            // 3자리 마다 콤마 표시 적용
          }
        });
      }
    });
  });
  // 특정 요소가 화면에 보이는지 여부를 확인하는 함수
  function isElementInViewport(el) {
    var rect = $(el)[0].getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }
</script>
답변을 작성하시기 전에 로그인 해주세요.
전체 1,020
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT