[javascirpt] 무한 롤링 이미지 배너 구현 - 1. 무한롤링 구현

인터넷을 검색해보면 자바스크립트로 구현된 많은 롤링 배너, 또는 슬라이드 배너를 찾을 수 있습니다.

제이쿼리 기반, 또는 순수 자바스크립트로 만들어진 많은 오픈소스 배너 라이브러리들이 있으며, 필요로 하는 대부분의 기능들이 이미 구현되어 있습니다.

기존에 구현된 슬라이딩 배너가 원하는 용도에 잘 맞는다면 이런 라이브러리를 사용하는 것을 추천합니다.

롤링 배너를 직접 구현해서 사용하는 것으로 인한 만족감은 상당히 높겠지만, 만족감을 빼면 오픈소스로 배포되는 잘 알려진 자바스크립트 롤링 배너 라이브러리가 여러가지 면에서 더 좋습니다.

하지만 오픈소스로 쉽게 구현되어 있다고 해도 결국은 다른 개발자가 작성한 코드입니다.

구현된 배너를 커스터마이징 하려면 기본적인 배너 구조와 코딩 로직 정도는 이해해야 하기 때문에, 결국 적지 않은 시간을 투자해야 합니다.

여기서는 순수 자바스크립트만으로 무한 롤링되는 배너를 구현해, 배너 라이브러리들이 어떤 방식으로 만들어지는지 전반적인 구조를 이해해 보도록 하겠습니다.

예제에서는 600 x 600px 이미지 3장 이상이 무한 롤링되는 배너를 만들어 보겠습니다.

최종적으로는 앞뒤 화살표 버튼으로 배너를 사용자가 이동할 수도 있도록 만들 예정입니다.

다양한 기능을 가진 완성도 있는 배너를 제작하려면 다양한 예외 상황에 대한 추가 처리를 해야 합니다.

예를 들어 이미지가 1장, 또는 2장만 있을 경우, 다양한 이미지 크기에 대한 대응 등 수많은 추가 기능을 구현해야 합니다.

이런 부분까지 구현하다보면 배너의 기초를 이해하는 것과는 너무 동떨어지게 되기 때문에 단순한 기능을 가지는 간단한 배너를 제작합니다.

 아래와 같이 HTML 페이지에 배너로 사용할 이미지 3장을 <ul></ul> 태그를 사용해 만듭니다.

외곽의 태그들은 가운데 정렬 및 배너 표시 영역 제한을 위한 레이아웃 입니다.

<div class="wrap_center">
  <div class="container">
    <div class="img_wrap">
      <ul class="rollimgs">
        <li><img src="./backup/692/img/banner1.jpg"></img></li>
        <li><img src="./backup/692/img/banner2.jpg"></img></li>
        <li><img src="./backup/692/img/banner3.jpg"></img></li>
      </ul>
    </div>
  </div>
</div>

아래와 같이 CSS를 적용하면

.wrap_center{
  width: 100%;
  height: 600px;
}
.container{
  margin: 0 auto;
  width: 600px;
  height: 600px;
  overflow: hidden;
}
.img_wrap{
  width: 600px;
  height: 600px;
  position: absolute;
  overflow: hidden;
}
/* 롤링 이미지 UL */
.rollimgs {
  list-style: none;
  padding: 0;
  margin: 0;
}

브라우저 가운데에 600 x 600px 이미지 배너 영역이 설정됩니다.

아직 이미지를 롤링하는 자바스크립트를 만들지 않았으므로 좌우로 이동한 이미지들이 보이지 않도록 되어있는 것을 알 수는 없습니다.

위의 클래스 중

.img_wrap{
  width: 600px;
  height: 600px;
  position: absolute;
  overflow: hidden;
}

이 클래스의 "overflow: hidden;" 속성(position: absolute 속성 필수)이 애니메이션 되는 배너 이미지를 600 x 600px 뷰포트 영역 안에서만 보이도록 만들어줍니다.

배너 이미지를 롤링 하는 방법은 다음 2가지를 사용합니다.

1. 클래스로 이전, 현재, 다음 이미지를 표시해 해당 이미지가 롤링되도록 함. 순차적으로 클래스를 다음 이미지로 이동시킴. 이미지 갯수를 알 필요가 없음.

2. 이미지 배열을 얻은 후, 이미지 인덱스를 순차적으로 이동하면서 현재 이미지와 다음 이미지에 애니메이션 클래스를 부여. 배너를 건너뛰는 조작 구현이 쉬움.

각각 장단점이 있으며, 여기서는 조금 더 단순하고 직관적인 1번으로 구현해봅니다.

먼저 롤링 이미지가 애니메이션 되면서 이동하려면 CSS로 애니메이션 트랜지션을 만들어 롤링되는 이미지들에 지정해야 합니다.

클래스로 이전(prev), 현재(current), 다음(next) 이미지에 이미지에 적용할 클래스를 만듭니다.

.rollimgs li{
    position: absolute;
    width: 600px;
    height: 600px;
    left: 600px;
}
.rollimgs li img{
    width: 100%;
    height: 100%;
}
.rollimgs li.currentroll{
    left: 0;
    transition: left .5s ease-in-out, right .5s ease-in-out;
}
.rollimgs li.prevroll{
    left: -600px;
    transition: left .5s ease-in-out, right .5s ease-in-out;
}
.rollimgs.reverse li.prevroll{
    transition: none;
}
.rollimgs li.nextroll{
    left: 600px;
    display: block;
    transition: none;
}
.rollimgs.reverse li.nextroll{
    transition: left .5s ease-in-out, right .5s ease-in-out;
}

"transition" 애니메이션 속성에 left, right 애니메이션 값이 모두 있는 것은, 나중에 배너 이동 버튼으로 원하는 방향으로 배너를 돌릴 수 있도록 하기 위한 것입니다.

이제 자바스크립트로 롤링 기능을 구현합니다.

롤링 배너 구현을 위한 객체 리터럴을 하나 만듭니다.

이름은 "banner" 로 합니다.

rollInit 메서드는 이미지에 초기 클래스를 부여합니다.

초기 클래스 부여 후 타이머를 이용해 일정 간격으로 배너 이미지가 다음 이미지로 롤링되도록 하는 rollNext 메서드를 호출합니다.

let banner = {
    rollId: null,
    interval: 2000,
    //롤링 배너 초기화
    rollInit: function (newinterval) {
        if(parseInt(newinterval) > 0){
            this.interval = newinterval;
        }
        //현재 배너
        let firstitem = document.querySelector('.rollimgs li');
        if(firstitem){
            firstitem.classList.add('currentroll');
        }
        //다음 배너
        let seconditem = document.querySelectorAll('.rollimgs li')[1];
        if(seconditem){
            seconditem.classList.add('nextroll');
        }
        //이전 배너
        document.querySelector('.rollimgs li:last-child').classList.add('prevroll');
        this.rollId = setInterval(this.rollNext, this.interval);//롤링 인터벌 호출    },
    //다음 배너 롤링
    rollNext: function () {
        if(document.querySelector('.prevroll')){
            document.querySelector('.prevroll').classList.remove('prevroll');
        }
        if(document.querySelector('.currentroll')){
            document.querySelector('.currentroll').classList.add('prevroll');
            document.querySelector('.currentroll').classList.remove('currentroll');
        }
        if(document.querySelector('.nextroll')){
            document.querySelector('.nextroll').classList.add('currentroll');
            document.querySelector('.nextroll').classList.remove('nextroll');
        }    //다음 이미지 있으면 다음 롤링 이미지로 선택, 없으면 첫번째 이미지를 롤링 이미지로 지정
        if(document.querySelector('.currentroll').nextElementSibling){
            document.querySelector('.currentroll').nextElementSibling.classList.add('nextroll');
        }else{
            document.querySelector('.rollimgs li').classList.add('nextroll');
        }
    }
}

DOM 로딩 직후 객체 리터럴 "banner" 의 초기화 메서드 "rollInit" 가 실행되도록 초기화용 이벤트 리스너를 하나 추가합니다.

document.addEventListener('DOMContentLoaded', function(){
  banner.rollInit(4000); // 배너 롤링
});

"rollInit" 메서드는 롤링 간격을 파라메터로 받아 객체 리터럴 "interval" 변수에 담습니다.

"interval" 변수 값은 "rollNext" 메서드가 주기적으로 실행되어 이미지가 롤링되는 시간 간격을 가지고 있습니다.

"rollNext" 메서드는 "prevroll", "currentroll", "nextroll" 클래스를 오른쪽 방향으로 한개씩 옮기는 역할을 합니다.

배너 이미지 끝에 도달하면 처음 이미지로 돌아가도록 조건절 처리가 되어있기 때문에 무한 롤링됩니다.

이제 설정한 시간 간격으로 이미지가 무한 롤링되는 것을 확인할 수 있습니다.

방향은 오른쪽에서 왼쪽으로 애니메이션 됩니다.

반대 방향으로 애니메이션되도록 하려면, 다음 강의에서 버

튼으로 반대 방향으로 애니메이션되는 기능을 구현하므로 그 메서드를 사용하면 됩니다.