오늘의 강의에서는 슬라이드 하단의 인디케이터와 관련된 이벤트들을 작성한다.
인디케이터와 관련된 이벤트 내용은 다음과 같다.
- 인디케이터 개수가 슬라이더 개수와 일치하도록 동적으로 생성하기
- 활성화된 인디케이터에는 특정한 클래스를 추가해주기
- 인디케이터를 클릭하면 해당 인덱스와 일치하는 슬라이드로 이동하고 해당 인디케이터에 활성화 클래스를 붙이기
1. 인디케이터 개수 동적으로 생성하기
HTML의 구조를 보면 indicator-wrap 안에는 ul이 들어있다. 그리고 ul 안에 슬라이드 개수만큼의 li를 동적으로 생성할 수 있도록 코드를 작성할 것이다.
// 동적으로 인디케이터 생성
createIndicator() {
// 여러개의 엘리먼트를 추가할때 사용. 렌더되지 않는다.
// 결과적으로 ul 안에 들어가는 것들은 li들 뿐.
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);
}
동적으로 인디케이터를 생성하는 코드는 다음과 같다.
for 문을 통해 li를 slideNumber만큼 반복해서 생성하고, data-index를 지정해준다.
data 속성을 지정해줄때는 dataset.원하는이름 형태로 작성하면 된다.
생성된 li는 createDocumentFragment로 생성한 Fragment에 담아준 뒤 indicator-wrap의 ul 안에 자식태그로 생성해준다.
💡 document.createDocumentFragment();
새로운 빈 documentFragment 객체를 생성한다. DOM 트리에 렌더링 되지는 않고, 메모리 상에만 따로 존재한다. DOM 조작에 앞서 잠시 보관해두는 빈 껍데기이다. 리액트의 <></> 와 같은 역할을 한다고 볼 수 있다.
2. 활성화된 인디케이터에 특정 클래스 추가하기
// 인디케이터 활성화 메서드
setIndicator() {
// index 전체 활성화 없음
// index에 따라서 활성화
this.indicatorWrapEl.querySelector('li.active')?.classList.remove('active');
this.indicatorWrapEl
.querySelector(`ul li:nth-child(${this.#currentPosition + 1})`)
.classList.add('active');
}
moveToRight() {
// ...
this.setIndicator(); // 인덱스가 변화할때마다 인디케이터 활성화 셋팅
}
moveToLeft() {
// ...
this.setIndicator(); // 인덱스가 변화할때마다 인디케이터 활성화 셋팅
}
인디케이터 활성화 메서드는 먼저 전체 인디케이터에서 활성화 클래스를 제거해준 뒤, 현재 슬라이드와 일치하는 인디케이터에만 활성화 클래스를 붙인다.
nth-child는 1부터 시작하고 currentPosition은 0부터 시작하기 때문에 1을 더해준다.
그리고 이전, 다음 버튼을 클릭했을때에도 인디케이터가 새로 세팅되어야 하기 때문에 각각의 메서드 내부에 setIndicator를 실행하도록 코드를 추가했다.
3. 인디케이터 클릭시 특정 슬라이드로 이동하게 하기
// 이벤트 메서드 작성
addEvent() {
// ...
this.indicatorWrapEl.addEventListener(
'click',
this.onClickIndicator.bind(this),
);
}
// 클릭시 해당 인덱스의 슬라이드로 이동
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();
}
}
모든 인디케이터에 일일이 이벤트를 걸어주는 것은 비효율적이기때문에, 이벤트 버블링을 이용해서 코드를 작성할것이다.
따라서 모든 인디케이터를 감싸고 있는 indicator-wrap에 이벤트를 걸어준다.
인디케이터의 data-index는 현재 string 타입이기때문에 parseInt 메서드를 사용해서 number 타입으로 변환한다.
그러나 클릭된 event.target이 li가 아닐경우(ul이나 indicator-wrap div) indexPosition이 undefined가 되기때문에 조건문을 통해 판별한다.
Number.isInteger() 메서드는 해당 값이 정수인지를 판별한다. 만약 undefined라면 NaN이 리턴되기때문에 코드는 실행되지 않을 것이다.
코드가 실행될 경우네는 currentPosition 값을 변경해주고 sliderList의 left 속성을 변경해준다.
그리고 setIndicator() 메서드를 실행해 클릭된 인디케이터에 활성화 클래스를 붙여준다.
***************************************
#패스트캠퍼스 #패캠챌린지 #수강료0원챌린지 #환급챌린지 #직장인인강 #직장인자기계발
#패캠인강후기 #패스트캠퍼스후기 #오공완 #30개프로젝트로배우는프론트엔드withReact
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
'study > fastcampus' 카테고리의 다른 글
[React] 이미지 슬라이드 - 3. next & prev (0) | 2023.02.27 |
---|---|
[React] 이미지 슬라이드 - 2. HTML & CSS (0) | 2023.02.26 |
[React] 이미지 슬라이드 - 1. 프로젝트 개요 및 개발환경 설정 (0) | 2023.02.25 |
[React] 가상 키보드 만들기 - 5. 마우스 이벤트 작성 (0) | 2023.02.24 |
[React] 가상 키보드 만들기 - 4. 키보드 이벤트 작성 (0) | 2023.02.23 |