스크롤 시 숫자카운팅 질문
본문
<!-- 숫자 인덱스 -->
<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>
한번만 하고 싶으시면 변수 값을 하나 만드셔서 true로 지정하고 카운팅이 되면 false로 하고 true 일때만 카운팅 되게 하시면 될거 같습니다.
모바일에서 안된다면 전체를 $(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>
답변을 작성하시기 전에 로그인 해주세요.