Image Slider

Ye Seo Lee·2023년 9월 18일
0

react30project

목록 보기
2/7
post-thumbnail

이미지 슬라이더

# 추후 도전 과제

  • 다른 슬라이드들은 어떤 기능이 있는지 찾아보기

# git link : imgSlide

# 개발 환경 : HTML5, CSS, Vanilla JS, Webpack, fontawesome

1. 개발환경 설정하기

1) npm & webpack 환경 설정

- webpack basic setting & plugin

  • 기본은 virtual Keyboard 랑 같음
  • fontawesome 설치 : npm i --save @fortawesome/fontawesome-free

2) 이미지 로더 설정

- webpack.config.js

{
  test: /\.jpeg$/,
  type: 'asset/inline',
}

- html (lodash 문법 적용)

<img src="<%= require('./file/root') %>" />

3) eslint 설정

  • airbnb eslint 설치 : npx install-peerdeps --dev eslint-config-airbnb
  • .eslint.trc 설정 : "extends": ["airbnb","plugin:prettier/recommended"]

2. next, prev 버튼

  • #currentPosition 의 값으로 슬라이드 위치 변경 (#slideWidth * #currentPosition)
  • 양 끝쪽에 도달하면 반대편 끝쪽으로 돌아가도록 설정
export default class ImageSlider {
  #currentPosition = 0;
  #slideNumber = 0;
	...

  constructor() {
    this.assignElement();
    this.initSliderNumber();
    this.initSlideWidth();
    this.initSliderListWidth();
    this.addEvent();
  }

  assignElement() {
    this.sliderWrapEl = document.getElementById('slider-wrap');
    this.sliderListEl = this.sliderWrapEl.querySelector('#slider');
    ...
  }

  initSliderNumber() {...}
  initSlideWidth() {...}
  initSliderListWidth() {...}

  addEvent() {
    this.nextBtnEl.addEventListener('click', ...);
    ...
  }

  moveToRight() {
    this.#currentPosition += 1;
    if (this.#currentPosition === this.#slideNumber) {
      this.#currentPosition = 0;
    }
    this.sliderListEl.style.left = `-${
      this.#slideWidth * this.#currentPosition
    }px`;
  }

  moveToLeft() {
    this.#currentPosition -= 1;
    if (this.#currentPosition === -1) {
      this.#currentPosition = this.#slideNumber - 1;
    }
    this.sliderListEl.style.left = `-${
      this.#slideWidth * this.#currentPosition
    }px`;
  }
}

3. indicator 버튼

  • 이미지 갯수에 따른 indicator 버튼 자동생성
    • #slideNumber 만큼 버튼을 만들어서 createDocumentFragment 로 가상으로 모았다가 부모 ul에 appendChild 함
    • dataset.index 추가 : 클릭에 따른 이동 기능 구현용
  • 클릭 시 슬라이드 이동 및 버튼 css 변경
    • active 클래스 토글로 버튼 상태 변화

export default class ImageSlider {
	...
  indicatorWrapEl;

  constructor() {
    ...
    this.createIndicator();
    this.setIndicator();
  }

  assignElement() {
    ...
    this.indicatorWrapEl = this.sliderWrapEl.querySelector('#indicator-wrap');
  }

  addEvent() {
    ...
    this.indicatorWrapEl.addEventListener('click', ...);
  }

  onClickIndicator(event) {
    const indexPosition = parseInt(event.target.dataset.index, 10);
    if(Number.isInteger(indexPosition)){
      this.#currentPosition = indexPosition;
      this.sliderListEl.style.left = `-${
        this.#slideWidth * this.#currentPosition
      }px`;
      this.setIndicator();
    }
  }
  
  createIndicator() {
    const docFragment = document.createDocumentFragment();
    for (let i = 0; i < this.#slideNumber; i += 1) {
      const li = document.createElement('li')
      li.dataset.index = i;
      docFragment.appendChild(li);
    }
    this.indicatorWrapEl.querySelector('ul').appendChild(docFragment)
  }

  setIndicator() {
    this.indicatorWrapEl
      .querySelector('li.active')
      ?.classList.remove('active');
    this.indicatorWrapEl
      .querySelector(`ul li:nth-child(${this.#currentPosition + 1})`)
      .classList.add('active');
  }
}

4. auto play 구현

  • setInterval과 clearInterval로 play/pause toggle 기능 구현
  • play/pause 상태에 따른 자동 슬라이드 기능 제어 구현
export default class ImageSlider {
  ...
  #intervalId;
  #autoPlay = true;
  controlWrapEl;


  constructor() {
    ...
    this.initAutoplay();
  }

  assignElement() {
    ...
    this.controlWrapEl = this.sliderWrapEl.querySelector('#control-wrap');
  }
  
  initAutoplay() {
    this.#intervalId = setInterval(this.moveToRight.bind(this), 3000);
  }

  addEvent() {
    ...
    this.controlWrapEl.addEventListener('click', ...);
  }


  togglePlay(event) {
    if(event.target.dataset.status === 'play') {
      this.#autoPlay = true;
      this.controlWrapEl.classList.add('play');
      this.controlWrapEl.classList.remove('pause');
      this.initAutoplay()

    } else if(event.target.dataset.status === 'pause') {
      this.#autoPlay = false;
      this.controlWrapEl.classList.remove('play');
      this.controlWrapEl.classList.add('pause');
      clearInterval(this.#intervalId);
    }
  }
  
  moveToRight() {
    ...
    if(this.#autoPlay) {
      clearInterval(this.#intervalId);
      this.#intervalId = setInterval(this.moveToRight.bind(this), 3000);
    }
    ...
  }

  moveToLeft() {
    ...
    if(this.#autoPlay) {
      clearInterval(this.#intervalId);
      this.#intervalId = setInterval(this.moveToRight.bind(this), 3000);
    }
    ...
  }
}




Learn more

#1. class 설정

  • class 변수 선언
    • private 변수 : #변수명
    • 일반 변수 : 별도 선언이 필수는 아니지만 리팩토링 측면에서 선언 해놓는 것이 좋음
  • 변수명 규칙 (정의된건 아니고 강의 보면서 이름별 특성을 정리한 것)
    • init~ : 무언가를 설정, 초기화, 값 변경 하는 기능의 함수명에 붙이는 앞머리명
    • move~ : 무언가를 움직이는 이벤트의 앞머리명
    • create~ : html 태그 생성 함수 앞머리명
    • onClick : click 이벤트 시 실행될 함수 앞머리명
    • set~ : 사용자의 행동에 따른 상태 변화(classList 변경 등) 셋팅하는 함수 앞머리명
    • assignElement : html에서 가져오는 태그를 변수에 할당하는 함수
    • addEvent : addEventListener로 이벤트 실행하는 함수

0개의 댓글