<div class="vertical_banner">
<ul class="list">
<li>아래에서 위로 흐르는 롤링 배너 1</li>
<li>아래에서 위로 흐르는 롤링 배너 2</li>
<li>아래에서 위로 흐르는 롤링 배너 3</li>
</ul>
</div>
<script>
jQuery(function($) {
const $wrap = $('.vertical_banner');
const $list = $('.vertical_banner .list');
let wrapHeight; // 배너 컨테이너의 높이
let listHeight; // 배너 리스트의 전체 높이
// 배너 리스트 복제 후 추가
let $clone = $list.clone();
$wrap.append($clone);
// 배너 애니메이션 처리하는 함수
function verticalBanner() {
// 배너 애니메이션 초기화
if (wrapHeight != '') {
$wrap.find('.list').css({
'animation': 'none'
});
$wrap.find('.list').slice(2).remove();
}
// 배너 컨테이너와 리스트 아이템의 현재 높이 가져오기
wrapHeight = $wrap.innerHeight();
listHeight = $list.innerHeight();
const speed = $list.find('li').innerHeight() / 2;
// 내용이 컨테이너보다 작은 경우 무한 반복을 만들기 위해 리스트를 복제하여 추가
if (listHeight < wrapHeight) {
const listCount = Math.ceil(wrapHeight * 2 / listHeight);
for (let i = 2; i < listCount; i++) {
$clone = $clone.clone();
$wrap.append($clone);
}
}
// 수직 롤링 효과를 위해 모든 리스트 아이템에 애니메이션 적용
$wrap.find('.list').css({
'animation': `${listHeight / speed}s linear infinite verticalRolling`
});
}
// 초기 배너 설정
verticalBanner();
// 창 크기에 따른 현재 디바이스 유형을 반환하는 함수
function getWindow() {
return window.innerWidth > 1280 ? 'pc' : window.innerWidth > 767 ? 'ta' : 'mo';
}
// 반응형 처리 설정
let oldWindow = getWindow();
$(window).on('resize', function () {
const newWindow = getWindow();
// 디바이스 유형이 변경된 경우에만 배너 롤링 재설정
if (newWindow !== oldWindow) {
oldWindow = newWindow;
verticalBanner();
}
});
// 마우스 이벤트 처리: 배너 롤링 일시 정지 및 재생
$wrap.on({
mouseenter: function () {
$wrap.find('.list').css('animation-play-state', 'paused');
},
mouseleave: function () {
$wrap.find('.list').css('animation-play-state', 'running');
}
});
});
</script>
<style>
.vertical_banner { overflow: hidden; width: 100%; height: 280px; max-width: 500px; margin: 30px auto; background: #f0f0f0; border-radius:20px; }
.vertical_banner .list > li { overflow: hidden; padding: 15px; font-size: 18px; color: #000; text-align: center; white-space: nowrap; text-overflow: ellipsis; }
@keyframes verticalRolling {
0% { transform: translateY(0); }
100% { transform: translateY(-100%); }
}
/* 반응형 스타일 */
@media (max-width: 1280px){
.vertical_banner { height: 240px; }
.vertical_banner .list > li { padding: 12px; font-size: 16px; }
}
@media (max-width: 767px){
.vertical_banner { height: 180px; }
.vertical_banner .list > li { padding: 8px; font-size: 14px; }
}
</style>