JS

μΊλŸ¬μ…€(Carousel)

choi95 2021. 7. 10. 23:17

 

μΊλŸ¬μ…€(Carousel)은 μœ„μ™€ 같이 컨텐츠λ₯Ό μŠ¬λΌμ΄λ“œ ν˜•νƒœλ‘œ μˆœνšŒν•˜λ©° ν‘œμ‹œν•˜λŠ” UIλ₯Ό λ§ν•œλ‹€.

 

μ΄λ•Œ λ¬΄ν•œ 루핑 κΈ°λŠ₯이 κ°€λŠ₯ν•˜κΈ° μœ„ν•΄μ„œλŠ” μ²˜μŒμ— 이미지 μŠ¬λΌμ΄λ“œμ—μ„œ 이전 λ²„νŠΌμ„ 클릭할 μ‹œ λ§ˆμ§€λ§‰ μŠ¬λΌμ΄λ“œλ‘œ 이동을 ν•˜κ³ 

λ°˜λŒ€λ‘œ λ§ˆμ§€λ§‰ μŠ¬λΌμ΄λ“œμ—μ„œ λ‹€μŒ λ²„νŠΌμ„ 클릭할 μ‹œ 처음 μŠ¬λΌμ΄λ“œλ‘œ 이동을 ν•΄μ•Ό ν•œλ‹€.

 

이λ₯Ό μœ„ν•΄ 본래 μ€€λΉ„λœ 총 4μž₯의 이미지 이외에 처음 λ‚˜μ˜€λŠ” 이미지와 λ§ˆμ§€λ§‰μ— λ‚˜μ˜€λŠ” 이미지λ₯Ό 각각 λ³΅μ‚¬ν•˜μ—¬ 자료ꡬ쑰의 μ–‘ 끝에 

μœ„μΉ˜μ‹œν‚¨λ‹€.

 

결과적으둜 μŠ¬λΌμ΄λ“œ μ΄λ―Έμ§€μ˜ 정보λ₯Ό λ‹΄κ³  μžˆλŠ” 자료ꡬ쑰의 맨 처음 μ΄λ―Έμ§€λŠ” λ§ˆμ§€λ§‰ μŠ¬λΌμ΄λ“œ 이미지이고 λ§ˆμ§€λ§‰ μ΄λ―Έμ§€λŠ” 처음

μŠ¬λΌμ΄λ“œ 이미지가 μ μž¬λœλ‹€. 

$container.addEventListener('click', e => {
    if(!e.target.classList.contains('carousel-control')) return;
      if(e.target.classList.contains('next')) { //λ‹€μŒ λ²„νŠΌμ„ λˆŒλ €μ„ 경우
        slides.style.setProperty('--currentSlide', ++currentSceneNum); //ν˜„μž¬ 씬에 맞게 이동
        slides.style.setProperty('--duration', 500);
        if(currentSceneNum > 5) { //ν˜„μž¬ 씬 μΈλ±μŠ€κ°€ λ§ˆμ§€λ§‰μΌ 경우
          slides.style.setProperty('--currentSlide', 1);
          slides.style.setProperty('--duration', 0);
          currentSceneNum = 1; // ν˜„μž¬ 씬 인덱슀λ₯Ό λ‹€μ‹œ 처음 씬에 λŒ€μ‘ν•˜λŠ” 인덱슀둜 μ΄ˆκΈ°ν™”
        }
      } else { //이전 λ²„νŠΌμ„ λˆŒλ €μ„ 경우
        slides.style.setProperty('--currentSlide', (--currentSceneNum));
        slides.style.setProperty('--duration', 500);
        if(currentSceneNum < 0) { //ν˜„μž¬ 씬 μΈλ±μŠ€κ°€ 처음일 경우
          slides.style.setProperty('--currentSlide', 4); //λ§ˆμ§€λ§‰ 씬에 λŒ€μ‘ν•˜λŠ” 인덱슀둜 μ΄ˆκΈ°ν™”
          slides.style.setProperty('--duration', 0);
          currentSceneNum = 4;
        }
      }
  })

μ΄λ•Œ 일반적으둜 μ•žλ’€λ‘œ μ›€μ§μ΄λŠ” 상황이 μ•„λ‹Œ 맨 μ²˜μŒμ΄λ‚˜ 맨 λ§ˆμ§€λ§‰μ—μ„œ 이동할 κ²½μš°μ—λŠ” transition의 duration 값은 0으둜 μ€˜μ•Όμ§€

μ‚¬μš©μž μ‹œμ μ—μ„œλŠ” μŠ¬λΌμ΄λ“œκ°€ 이동이 λ˜μ—ˆλŠ”μ§€ κ°€μ‹œμ μœΌλ‘œ 인지 λͺ»ν•˜κ²Œ ν•  수 μžˆλ‹€.

 

transitionend Event

λ¬΄ν•œ 루핑 κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄μ„œ Click 이벀트 λ‚΄μ—μ„œ μ²˜λ¦¬ν•΄μ•Ό 될 쑰건 연산듀이 λ„ˆλ¬΄ λ§Žμ•„μ Έμ„œ μ½”λ“œμ˜ νš¨μœ¨μ„±λ„ λΆ€μ‘±ν•˜κ³  가독성도 λ–¨μ–΄μ‘Œλ‹€. μœ„μ˜ μ½”λ“œλ₯Ό λŒ€μ‹ μ— transitionend 이벀트λ₯Ό μ‚¬μš©ν•˜κ³ μž ν•œλ‹€.

transitionendλŠ” μ „ν™˜ μƒνƒœλ₯Ό μ „ν™˜ μ™„λ£Œλ‘œ, κΈ°λ³Έ λ˜λŠ” λΉ„ μ „ν™˜ μƒνƒœλ‘œ μ™„μ „νžˆ λ˜λŒμ•„ κ°„λ‹€ - μ΄λ²€νŠΈκ°€ μ–‘λ°©ν–₯으둜 λ°œμƒν•©λ‹ˆλ‹€. 
$container.ontransitionend = () => {
    isMoving = false;

    // currentSlide === 0, 즉 선두에 μΆ”κ°€ν•œ 클둠 μŠ¬λΌμ΄λ“œλ©΄ currentSlide += images.length둜 image의 λ§ˆμ§€λ§‰(images.length)으둜 이동
    // currentSlide === images.length + 1, 즉 λ§ˆμžλ§‰μ— μΆ”κ°€ν•œ 클둠 μŠ¬λΌμ΄λ“œλ©΄ currentSlide -= images.length둜 image의 선두(1)둜 이동
    // 클둠 μŠ¬λΌμ΄λ“œκ°€ μ•„λ‹ˆλ©΄ currentSlide += 0으둜 μ΄λ™ν•˜μ§€ μ–ΊλŠ”λ‹€.
    const delta = currentSlide === 0 ? 1 : currentSlide === images.length + 1 ? -1 : 0;

    // 클둠 μŠ¬λΌμ΄λ“œκ°€ μ•„λ‹ˆλ©΄(delta === 0) μ΄λ™ν•˜μ§€ μ•ŠλŠ”λ‹€.
    if (!delta) return;

    currentSlide += images.length * delta;
    move(currentSlide);
  };
};