[javascript] 무한 롤링 이미지 배너 구현 - 2. 앞뒤 이동 버튼 구현

한 방향으로만 무한 롤링되는 배너에 양방향 이동 화살표를 추가해 사용자 조작으로 배너를 돌려볼 수 있도록 기능을 개선해 보겠습니다.

먼저 이동 화살표 이미지는 폰트어썸(FontAwesome) 오픈소스 벡터 아이콘 이미지를 가져와 사용합니다.

HTML 페이지 헤더 영역에 폰트어썸 아이콘 CSS 링크를 추가합니다.

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" crossorigin="anonymous">

이전, 다음 화살표 아이콘을 롤링 이미지들 앞쪽에 추가합니다.

<div class="img_wrap">
  <div class="prev btnmove">
    <a href="#" title="이전"><i class="fas fa-chevron-left"></i></a>
  </div>
  <div class="next btnmove">
    <a href="#" title="다음"><i class="fas fa-chevron-right"></i></a>
  </div>
  <ul class="rollimgs">
    <li><img src="./backup/707/img/banner1.jpg"></img></li>
    <li><img src="./backup/707/img/banner2.jpg"></img></li>
    <li><img src="./backup/707/img/banner3.jpg"></img></li>
  </ul>
</div>

위치를 잡기 위해 화살표 아이콘 위치를 CSS로 지정해줍니다.

CSS가 적용되면 반투명한 화살표 2개가 롤링 이미지 좌우의 고정된 위치에 배치되어 보입니다.

.img_wrap .btnmove{
  position: absolute;
  top: 268px;
  width: 40px;
  height: 85px;
  z-index: 1;
  font-size: 4em;
  opacity: 0.5;
}
.img_wrap .btnmove.prev{
  left: 10px;
}
.img_wrap .btnmove.next{
  right: 10px;
}
.img_wrap i{
  color: #fff;
}

초기화 이벤트 리스너에 화살표 클릭 이벤트 리스너를 추가합니다.

좌우 버튼을 눌렀을 때 어느 버튼이 눌렸는지 클래스로 구분해서 오른쪽으로 롤링할지, 왼쪽으로 롤링할지를 결정합니다.

//앞뒤 클릭 이벤트 리스너
document.querySelectorAll('.btnmove').forEach(function(item){
  item.addEventListener('click', function(e){
    clearInterval(banner.rollId);//롤링 인터벌 해제
    //화살표 방향 구분
    if(e.target.parentElement.parentElement.classList.contains('prev')){
      banner.rollPrev();
    }else{
      banner.rollNext();
    }
    banner.rollId = setInterval(banner.rollNext, banner.interval);//롤링 인터벌 재호출
  });
}); 

"prev" 클래스가 있으면(e.target.parentElement.parentElement.classList.contains('prev')) 왼쪽 배너로, 없으면 오른쪽 배너로 이동합니다.

이벤트 처리 앞뒤를 보면 앞에는 타이머 객체를 해제하고, 롤링 메서드 호출 후에 타이머 객체를 다시 생성하는 것을 볼 수 있습니다.

이것은 타이머가 돌고 있는 중일 경우 이벤트 클릭과 중복으로 실행되어, 배너가 2개가 한꺼번에 이동하거나, 이동하다 되돌아오는 충돌현상을 막기 위한 것입니다.

사용자 클릭에 의한 롤링이 호출된 후 타이머를 다시 시작해 사용자 액션과 타이머 액션이 중복되지 않도록 하기 위한 고급 기법입니다.

오른쪽 방향으로 롤링하는 메서드(rollNext)는 이미 구현되어 있으므로, 왼쪽 방향으로 롤링하는 메서드를 추가로 구현해서 객체 리터럴에 추가합니다.

//이전 배너 롤링
rollPrev: function () {
  document.querySelector('.rollimgs').classList.add('reverse');
  if(document.querySelector('.nextroll')){                       
    document.querySelector('.nextroll').classList.remove('nextroll');
  }
  if(document.querySelector('.currentroll')){
    document.querySelector('.currentroll').classList.add('nextroll');
    document.querySelector('.currentroll').classList.remove('currentroll');
  }
  if(document.querySelector('.prevroll')){
    document.querySelector('.prevroll').classList.add('currentroll');
    document.querySelector('.prevroll').classList.remove('prevroll');
  }
  if(document.querySelector('.currentroll').previousElementSibling){    
    document.querySelector('.currentroll').previousElementSibling.classList.add
('prevroll');
  }else{
    document.querySelector('.rollimgs li:last-child').classList.add('prevroll');
  }
}

이제 화살표 버튼을 클릭하면 원하는 방향으로 배너를 돌려가면서 볼 수 있습니다.

화살표 클릭이 더 이상 없으면, 지정된 시간 간격으로 다시 오른쪽 방향으로 배너가 무한 롤링됩니다.

배너를 반대 방향으로 무한 롤링 하려면 

초기화 이벤트 리스너와, 객체 리터럴의 초기화 메서드(rollInit) 에서 호출하는 타이머 함수의 "rollNext" 를 "rollPrev" 로 변경해주면 됩니다.

this.rollId = setInterval(this.rollPrev, this.interval);//롤링 인터벌 호출