초기 로직 세팅
이벤트가 발생하면 (prev 또는 next버튼 클릭)
class ImageSlider extends Component<PropsType> {
state: number;
maxLength: number;
constructor($target: Element, props: PropsType) {
super($target, props);
this.state = 1;
this.maxLength = this.props.imageUrlList.length;
this.render();
this.activeSlide(true);
}
setState(nextState: number) {
if (nextState > this.maxLength) {
this.state = 1;
return;
}
if (nextState < 1) {
this.state = this.maxLength;
return;
}
this.state = nextState;
}
template(): string {
return `
<div class='Image-slider-container'>
<div class='image-slider'>
<ul class='slider-list'>
${this.props.imageUrlList
.map(url => `<li class='slider-item fade '><img src="${url}"></li>`)
.join('')}
</ul>
<button class='prev'>❮</button>
<button class='next'>❯</button>
</div>
<div class='dots'>
${this.props.imageUrlList
.map((_, i) => `<span class='dot dot_${i}'></span>`)
.join('')}
</div>
</div>
`;
}
_setCurrentItemBlock(param: boolean) {
const currentItem = document.querySelector(
`.slider-item:nth-child(${this.state})`,
);
if (currentItem instanceof HTMLElement) {
currentItem.style.display = param ? 'block' : 'none';
}
}
_setCurrentDotOn(param: boolean) {
const currentDot = document.querySelector(`.dot_${this.state - 1}`);
if (currentDot instanceof HTMLElement) {
currentDot.style.backgroundColor = param ? '#717171' : '#bbb';
}
}
activeSlide(param: boolean) {
this._setCurrentItemBlock(param);
this._setCurrentDotOn(param);
}
handleClickButton(status: string) {
this.activeSlide(false);
this.setState(status === 'prev' ? this.state - 1 : this.state + 1);
this.activeSlide(true);
}
mount() {
const prevButton = document.querySelector('.prev');
const nextButton = document.querySelector('.next');
prevButton?.addEventListener('click', () => {
this.handleClickButton('prev');
});
nextButton?.addEventListener('click', () => {
this.handleClickButton('next');
});
}
render() {
this.$target.innerHTML = '';
this.$target.innerHTML = this.template();
this.mount();
}
}
export default ImageSlider;