자바스크립트

[JavaScript] 이미지 슬라이드

코딩하는둥이 2025. 3. 20. 14:19

 

 

 

캐러셀의 기능을 구현하기 위해 Carousel 클래스 생성해줍니다. 

  class Carousel {
    constructor(carouselElement) {
      this.carouselElement = carouselElement // 캐러셀을 감싸는 요소(div)
      this.itemClassName = 'carousel_item' // 캐러셀 내의 각 이미지 요소의 클래스 이름
      this.items = this.carouselElement.querySelectorAll('.carousel_item') // 캐러셀 내의 모든 이미지 요소들을 배열로 저장

      this.totalItems = this.items.length // 캐러셀에 있는 이미지의 총 개수
      this.current = 0 // 현현재 보여지는 이미지의 인덱스
    }
  }

 


 HTML 문서의 콘텐츠가 모두 로드되었을 때 발생하는 DOMContentLoaded 이벤트를  생성해줍니다.

 

document.addEventListener('DOMContentLoaded', () => {
  const carouselElement = get('.carousel') 

  const carousel = new Carousel(carouselElement) // 인스턴스 생성
})

 

버튼에 이벤트 리스를 설정하는 메서드를 생성해줍니다.

    setEventListeners() {
      this.prevButton = this.carouselElement.querySelector(
        '.carousel_button--prev' 
      )
      this.nextButton = this.carouselElement.querySelector(
        '.carousel_button--next'
      )

      this.prevButton.addEventListener('click', () => {
        this.movePrev()
      })
      this.nextButton.addEventListener('click', () => {
        this.moveNext()
      })
    }

 

마지막 이미지에 도달했을 때 첫번째 사진으로 이동하도록 예외처리를 해줍니다. 

moveNext() {
  if (!this.isMoving) {
    if (this.current === this.totalItems - 1) {
      this.current = 0
    } else {
      this.current++
    }

    this.moveCarouselTo()
  }
}

 

첫번째 이미지에 도달했을 때 마지막 사진으로 이동하도록 예외처리 해줍니다. 

movePrev() {
  if (!this.isMoving) {
    if (this.current === 0) {
      this.current = this.totalItems - 1
    } else {
      this.current--
    }

    this.moveCarouselTo()
  }
}

 

이제 이미지를 움직이게 해주는 moveCarouselTo 메서드를 만듭니다. 

만약에 두번째 사진이 보인 상태라면 첫번째 사진에 prev의 클라스가 붙게되고 세번째 사진에는 next 클래스 붙게되고 두번째 사진은 active가 됩니다. 

 moveCarouselTo() {
  if (!this.isMoving) {
    let prev = this.current - 1 
    let next = this.current + 1

    if (this.current === 0) {
      prev = this.totalItems - 1
    } else if (this.current === this.totalItems - 1) {
      next = 0
    }

    for (let i = 0; i < this.totalItems; i++) {
      if (i == this.current) {
        this.items[i].className = this.itemClassName + ' active'
      } else if (i == prev) {
        this.items[i].className = this.itemClassName + ' prev'
      } else if (i == next) {
        this.items[i].className = this.itemClassName + ' next'
      } else {
        this.items[i].className = this.itemClassName
      }
    }
  }

 

캐러셀을 초기화해줍니다

initCarousel() {
  this.isMoving = false

  this.items[this.totalItems - 1].classList.add('prev')
  this.items[0].classList.add('active')
  this.items[1].classList.add('next')
}

 

 

이제 초기화하는 메서드와 캐러셀에 이벤트 리스너를 실행하는 메서드를 호출해줍니다,

  document.addEventListener('DOMContentLoaded', () => {
    const carouselElement = get('.carousel')

    const carousel = new Carousel(carouselElement)
    carousel.initCarousel()
    carousel.setEventListeners()
  })

 

이렇게까지만 해도 슬라이드 기능은 다 완성되었지만, 한가지 오류가 있습니다.

바로, 슬라이더가 동작하는 동안 버튼을 클릭해도 슬라이드가 이동되는데요, 

일정시간동안 상호 작용을 방지하는 기능을 추가할 것입니다.

 

먼저 isMoving이 ture만 동작하고 5초동안 isMoving false을 줍니다.

disableInteraction() {
  this.isMoving = true
  setTimeout(() => {
    this.isMoving = false
  }, 500)
}

 

이 기능을 이제 추가해줍니다.

class Carousel {
    constructor(carouselElement) {
      this.carouselElement = carouselElement
      this.itemClassName = 'carousel_item'
      this.items = this.carouselElement.querySelectorAll('.carousel_item')

      this.totalItems = this.items.length
      this.current = 0
      this.isMoving = false
    }

    initCarousel() {
      this.isMoving = false

      this.items[this.totalItems - 1].classList.add('prev')
      this.items[0].classList.add('active')
      this.items[1].classList.add('next')
    }

    disableInteraction() {
      this.isMoving = true
      setTimeout(() => {
        this.isMoving = false
      }, 500)
    }

    moveCarouselTo() {
      if (!this.isMoving) {
        this.disableInteraction()

        let prev = this.current - 1
        let next = this.current + 1

        if (this.current === 0) {
          prev = this.totalItems - 1
        } else if (this.current === this.totalItems - 1) {
          next = 0
        }

        for (let i = 0; i < this.totalItems; i++) {
          if (i == this.current) {
            this.items[i].className = this.itemClassName + ' active'
          } else if (i == prev) {
            this.items[i].className = this.itemClassName + ' prev'
          } else if (i == next) {
            this.items[i].className = this.itemClassName + ' next'
          } else {
            this.items[i].className = this.itemClassName
          }
        }
      }
    }

    moveNext() {
      if (!this.isMoving) {
        if (this.current === this.totalItems - 1) {
          this.current = 0
        } else {
          this.current++
        }

        this.moveCarouselTo()
      }
    }

    movePrev() {
      if (!this.isMoving) {
        if (this.current === 0) {
          this.current = this.totalItems - 1
        } else {
          this.current--
        }

        this.moveCarouselTo()
      }
    }
}

 

그러면 슬라이드 기능을 완성했습니다.

;(function () {
  'use strict'

  const get = (target) => {
    return document.querySelector(target)
  }

  class Carousel {
    constructor(carouselElement) {
      this.carouselElement = carouselElement
      this.itemClassName = 'carousel_item'
      this.items = this.carouselElement.querySelectorAll('.carousel_item')

      this.totalItems = this.items.length
      this.current = 0
      this.isMoving = false
    }

    initCarousel() {
      this.isMoving = false

      this.items[this.totalItems - 1].classList.add('prev')
      this.items[0].classList.add('active')
      this.items[1].classList.add('next')
    }

    setEventListeners() {
      this.prevButton = this.carouselElement.querySelector(
        '.carousel_button--prev'
      )
      this.nextButton = this.carouselElement.querySelector(
        '.carousel_button--next'
      )

      this.prevButton.addEventListener('click', () => {
        this.movePrev()
      })
      this.nextButton.addEventListener('click', () => {
        this.moveNext()
      })
    }

    disableInteraction() {
      this.isMoving = true
      setTimeout(() => {
        this.isMoving = false
      }, 500)
    }

    moveCarouselTo() {
      if (!this.isMoving) {
        this.disableInteraction()

        let prev = this.current - 1
        let next = this.current + 1

        if (this.current === 0) {
          prev = this.totalItems - 1
        } else if (this.current === this.totalItems - 1) {
          next = 0
        }

        for (let i = 0; i < this.totalItems; i++) {
          if (i == this.current) {
            this.items[i].className = this.itemClassName + ' active'
          } else if (i == prev) {
            this.items[i].className = this.itemClassName + ' prev'
          } else if (i == next) {
            this.items[i].className = this.itemClassName + ' next'
          } else {
            this.items[i].className = this.itemClassName
          }
        }
      }
    }

    moveNext() {
      if (!this.isMoving) {
        if (this.current === this.totalItems - 1) {
          this.current = 0
        } else {
          this.current++
        }

        this.moveCarouselTo()
      }
    }

    movePrev() {
      if (!this.isMoving) {
        if (this.current === 0) {
          this.current = this.totalItems - 1
        } else {
          this.current--
        }

        this.moveCarouselTo()
      }
    }
  }

  document.addEventListener('DOMContentLoaded', () => {
    const carouselElement = get('.carousel')

    const carousel = new Carousel(carouselElement)
    carousel.initCarousel()
    carousel.setEventListeners()
  })
})()