올해 상반기 프로그래머스 Dev-Matching을 준비하면서, 지난해 상반기 과제를 풀어보았다.
과제 개요
https://programmers.co.kr/skill_check_assignments/100
고양이 사진과 파일 정보가 담긴 API로 일종의 사진 탐색기를 만드는 것이 과제이다. 다른 모듈을 사용하지 않고 바닐라 JavaScript로 만들어야 하며, 제한 시간은 3시간이었다.
우선 첫 화면(root)을 렌더링하는 함수를 구현했다. async/await 비동기 함수로 만들었고, 여기서 Loading은 로딩 화면을 렌더링하는 함수다.
async function Root() {
Loading();
const apiurl = "https://zl3m4qq0l9.execute-api.ap-northeast-2.amazonaws.com/dev";
let rootdata = await fetch(apiurl, {
method: 'GET',
})
.then(res => res.json())
.catch(res => console.log(res.json()));
await RootRender(rootdata);
};
그 다음으론 싱글 페이지로 구현(SPA)해야 해서, 폴더나 이미지를 클릭했을 때 화면을 렌더링하는 함수를 구현했다. e.target.closest과 dataset을 활용해 선택한 항목의 이름과 타입(폴더인지 파일인지), 이미지 링크를 가져오는 방식이다.
function Click() {
Nodes.addEventListener("click", (e) => {
let selected = e.target.closest("div").id;
let selectedName = e.target.closest("div").dataset.item;
let selectedType = e.target.closest("div").dataset.type;
let selectedImg = e.target.closest("div").dataset.file;
if (selected && selectedType === "directory") {
Depth.push(selected);
DepthName.push(selectedName);
DepthNameRender();
NotRoot(selected, selectedName);
} else if (selected && selectedType === "file") {
ViewImg(selectedImg);
} else {
Depth.pop();
DepthName.pop();
DepthNameRender();
Depth[Depth.length-1] ? NotRoot(Depth[Depth.length-1]) : Root();
}
});
};
코드 전체
const appwrap = document.querySelector(".App");
const Nodes = appwrap.querySelector(".Nodes");
const Bread = appwrap.querySelector(".Breadcrumb");
const Depth = [null];
const DepthName = ['root'];
function Loading() {
Nodes.innerHTML = `
<div class="Loading">
</div>
`;
}
function ViewImg(file) {
appwrap.insertAdjacentHTML('beforeend', `
<div class="Modal ImageViewer">
<div class="content">
<img src="https://fe-dev-matching-2021-03-serverlessdeploymentbuck-t3kpj3way537.s3.ap-northeast-2.amazonaws.com/public${file}" width="450px">
</div>
`);
const ViewerModal = document.querySelector(".ImageViewer");
ViewerModal.addEventListener("click", (e) => {
if (e.target.classList.contains("Modal")){
ViewerModal.remove();
};
})
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
ViewerModal.remove();
}
});
};
function DepthNameRender() {
Bread.innerHTML = DepthName.map((value) => {
return `<div>${value}</div>`;
}).join("");
};
function RootRender(data) {
Nodes.innerHTML = data.map((ele) => {
return `<div class="Node" id=${ele.id} data-item=${ele.name} data-type=${ele.type.toLowerCase()} data-file=${ele.filePath}>
<img src="./assets/${ele.type.toLowerCase()}.png">
<div>${ele.name}</div>
</div>
`
}).join("");
};
function NotRootRender(data) {
console.log(data);
const prev = `<div class="Node" data-type="prev">
<img src="./assets/prev.png">
</div>
`;
Nodes.innerHTML = prev + data.map((ele) => {
return `<div class="Node" id=${ele.id} data-item=${ele.name} data-type=${ele.type.toLowerCase()} data-file=${ele.filePath}>
<img src="./assets/${ele.type.toLowerCase()}.png">
<div>${ele.name}</div>
</div>
`
}).join("");
};
function Click() {
Nodes.addEventListener("click", (e) => {
let selected = e.target.closest("div").id;
let selectedName = e.target.closest("div").dataset.item;
let selectedType = e.target.closest("div").dataset.type;
let selectedImg = e.target.closest("div").dataset.file;
if (selected && selectedType === "directory") {
Depth.push(selected);
DepthName.push(selectedName);
DepthNameRender();
NotRoot(selected, selectedName);
} else if (selected && selectedType === "file") {
ViewImg(selectedImg);
} else {
Depth.pop();
DepthName.pop();
DepthNameRender();
Depth[Depth.length-1] ? NotRoot(Depth[Depth.length-1]) : Root();
}
});
};
async function Root() {
Loading();
const apiurl = "https://zl3m4qq0l9.execute-api.ap-northeast-2.amazonaws.com/dev";
let rootdata = await fetch(apiurl, {
method: 'GET',
})
.then(res => res.json())
.catch(res => console.log(res.json()));
await RootRender(rootdata);
};
async function NotRoot(itemId) {
Loading();
const apiurl = "https://zl3m4qq0l9.execute-api.ap-northeast-2.amazonaws.com/dev/"+itemId;
let getdata = await fetch(apiurl, {
method: 'GET',
})
.then(res => res.json())
.catch(res => console.log(res.json()));
await NotRootRender(getdata);
};
Root();
Click();
'CODE > Front-end' 카테고리의 다른 글
Redux-toolkit으로 로그인 구현 (1) state 저장하기 (0) | 2022.07.20 |
---|---|
[JS] 최적화 (0) | 2021.12.21 |
[JS] 로또 번호 만들기 (0) | 2021.12.04 |
[JS] 함수 선언문과 함수 표현식 (0) | 2021.12.01 |
[JS] 데이터 형, 연산, 조건문과 반복문 (0) | 2021.11.30 |
댓글