main.js ← App.js ← api/api.js
← components(floder) ← SearchInput.js
← SearchError.js
← SearchKeyword.js
← SearchResult.js
← ImageInfo.js
← ImageBanner.js
← Loading.js
← lib ← LocalStorage.js
← LazyLoading.js
검색 결과 목록 위 배너 형태의 랜덤 고양이 섹션을 추가해야합니다. 조건은 다음과 같습니다.
🐇 배너 데이터
앱이 구동되면 데이터를 요청하여 섹션에 넣어야한다. 해당 값을 관리하는 banner
변수를 생성하고, App.js에서 init시 데이터를 할당해준다.
App.js
...
export default function App($app) {
this.state = {
...
banner: [],
};
...
const init = async () => {
const initData = await request("random");
this.setState({
...this.state,
banner: initData,
data,
});
const storage = getLocalStorage();
if (!storage || !storage.data || !storage.data.length) {
return;
}
this.setState({
...this.state,
loading: false,
data: storage.data,
});
};
init();
}
슬라이드를 만드는 방법은 다양합니다.
사용자에게 보이는 화면만을 고려하여 보여지는 요소와 가려진 요소의 크기를 고려하여 요소 전체를 좌우로 미는 형태로 구현되는 모습입니다.
구현방식은 슬라이드 리스트 내 요소를 삭제하고 추가하는 방식입니다. 마지막 조건에 따라서 전체를 삭제하고 추가하는 형태로 구현하셔도 좋습니다.
본 개발은, 마지막 조건에서 좌, 우 버튼 클릭 시 1개의 이미지가 사라지고 추가되는 형태로 구현되었습니다.
ImageBanner.js
export default function ImageBanner({ $app, initialState }) {
this.state = initialState;
this.$target = document.createElement("div");
this.$target.className = "SlideShow";
this.$prev = document.createElement("span");
this.$prev.className = "prev";
this.$prev.innerHTML = `⟨`;
this.$slide = document.createElement("ul");
this.$slide.className = "Slides";
this.$next = document.createElement("span");
this.$next.className = "next";
this.$next.innerHTML = `⟩`;
this.$target.appendChild(this.$prev);
this.$target.appendChild(this.$slide);
this.$target.appendChild(this.$next);
$app.appendChild(this.$target);
this.setState = (nextState) => {
this.state = nextState;
this.render();
};
this.render = () => {
this.$slide.innerHTML = this.state
.slice(0, 5)
.map((cat, index) => {
return `
<li>
<img src="${cat.url}" title="${cat.name}" data-index="${index}"/>
</li>`;
})
.join("");
};
const changeSlides = (type) => {
//좌, 우 버튼 선택에 따라 세부 조건을 변경
type = type === "prev" ? true : false;
const $slide = document.querySelector("ul");
//좌 버튼을 누르는 경우 마지막요소를 선택
//우 버튼을 누르는 겨웅 첫번째요소를 선택
const $slideChild = $slide.querySelector(
type ? "li:last-child" : "li:first-child"
);
const $slideImg = $slideChild.querySelector("img");
const { index } = $slideImg.dataset;
//새로운 요소의 데이터 인덱스 조정
const idx = parseInt(index, 10) + (type ? -5 : +5);
if (idx >= 0 && idx < this.state.length) {
//선택한 요소 삭제
$slideChild.remove();
//삭제된 요소의 위치에 맞게 새 요소를 추가
const $slideItem = document.createElement("li");
$slideItem.innerHTML = `
<img src="${this.state[idx].url}" title="${this.state[idx].name}" data-index="${idx}"/>
`;
type ? $slide.prepend($slideItem) : $slide.appendChild($slideItem);
}
};
this.$prev.addEventListener("click", () => {
changeSlides("prev");
});
this.$next.addEventListener("click", () => {
changeSlides("next");
});
this.render();
}
App.js
...
import ImageBanner from "./components/ImageBanner.js";
...
export default function App($app) {
...
const imageBanner = new ImageBanner({
$app,
initialState: [],
});
...
this.setState = (nextState) => {
this.state = nextState;
...
imageBanner.setState(this.state.banner);
};
...
}
추후 트랜지션을 적용하면, setInterval()를 이용하여 prev, lang버튼을 클릭하여 조절합니다.