모바일 스크롤 이벤트 질문드립니다
본문
<!-- 숫자 인덱스 -->
<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 class="num-item2">
<span class="nums" data-count="19912">1000</span><span id="num-unit">건</span><br>
</div>
</div>
<style>
@media (max-width: 768px) {
.num-container {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
background-repeat: no-repeat;
width: 423px;
height: 250px;
text-align: center;
margin: 0 auto;
}
.num-item, .num-item2 {
text-align: center;
padding-top: 0%;
padding-left: 10%;
}
.nums {
font: bold 37px/1 'arial';
color: #fff;
}
}
</style>
<script>
$(document).ready(function() {
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>
스크롤 해서 해당 부분에 도착하면 카운팅 되도록 만들었습니다. 그런데 pc에서는 정상적으로 작동하는데 모바일에서는 스크롤 해서 해당 부분에 도착하면 이미 카운팅이 끝나있습니다. 해결 방법이 있을까요?
!-->
답변 2
안녕하세요.
아래의 내용을 한번 참고해 보시겠어요~
<!-- 숫자 인덱스 -->
<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 class="num-item2">
<span class="nums" data-count="19912">1000</span><span id="num-unit">건</span><br>
</div>
</div>
<!-- CSS 생략 -->
<script>
$(document).ready(function() {
var counted = false;
// 페이지 로딩 완료 시점에도 카운팅 여부 확인 (수정된 부분)
if (!counted && isElementInViewport('.num-container')) {
startCounting();
}
$(window).scroll(function() {
if (!counted && isElementInViewport('.num-container')) {
startCounting();
}
});
function startCounting() { // 새로 추가된 함수
counted = 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>
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
IntersectionObserver 를 활용 하시는게 좋아 보입니다.
특정 포인트가 화면에 출력 되느냐 않느냐 판단 가능하거든요