index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<script src="js/main.js" defer></script>
<title>Document</title>
</head>
<body>
<div>
<!-- 로고 -->
<div class="logoDiv">
<img src="imgs/logo.png" alt="logo" class="logo">
</div>
<!-- 버튼 -->
<div class="buttonDiv">
<button class="btn"><img src="imgs/blue_t.png" class="imgBtn" alt="tshirt" data-key="type" data-value="tshirt"></button>
<button class="btn"><img src="imgs/blue_p.png" class="imgBtn" alt="pants" data-key="type" data-value="pants"></button>
<button class="btn"><img src="imgs/blue_s.png" class="imgBtn" alt="skirt" data-key="type" data-value="skirt"></button>
<button class="btn colorBtn blue" data-key="color" data-value="blue">Blue</button>
<button class="btn colorBtn yellow" data-key="color" data-value="yellow">Yellow</button>
<button class="btn colorBtn pink" data-key="color" data-value="pink">Pink</button>
</div>
<!-- 리스트 -->
<ul class="items">
<li class="item">
<img src="imgs/blue_s.png" alt="skirt" class="item_thumbnail">
<span>남성 라지</span>
</li>
</ul>
</div>
</body>
</html>
js > main.js
//json파일을 받아오는 함수
function loadItems(){
//json데이터를 fetch를 통해 받아옴
// fetch api
// fetch('url') --> 네트워크 주소를 적으면 받아옴
return fetch('data/data.json')
//성공적으로 데이터를 받으면 제이슨으로 변환하여 리턴
// 파일량에 따라 불러오는 시간이 다름
.then(response => response.json()) // () 소괄호 생략 가능
//변환이 성공하면 json매개변수에 받아서 json의 key items값을 리턴
.then(json => json.items);
}
//받아온 json데이터를 html요소로 변환하여 화면에 나타내기!
function displayItems(items){
const container = document.querySelector('.items');
container.innerHTML = items.map(abc => createHTMLString(abc)).join('');
// = items.map(abc => {
// return createHTMLString(abc);
// }).join(''); // 문자열로 바꿔줌
}
//html스트링으로 변경
function createHTMLString(item){
return `
<li class="item">
<img src=${item.image} alt=${item.type} class="item_thumbnail">
<span>${item.gender} ${item.size}</span>
</li>
`;
}
//이벤트 함수
function setEventListerners(items){
const logo = document.querySelector('.logo');
const buttons = document.querySelector('.buttonDiv');
logo.addEventListener('click', () => displayItems(items));
// logo.addEventListener('click', function(){
// displayItems(items);
// });
buttons.addEventListener('click', event => onButtonClick(event, items));
// buttons.addEventListener('click', function(event){
// onButtonClick(event, items);
// });
}
// 버튼을 틀릭할 때 실행되는 함수
function onButtonClick(event, items){
const dataset = event.target.dataset;
const key = dataset.key;
const value = dataset.value;
// key 와 value 값 중 하나라도 없으면 종료
if(key == null || value == null){
return; // 함수는 리턴하면 끝남, 반복문은 브레이크 🧡
}
// 해당하는 리스트만 뿌려주기
// filter() 해당하는 조건을 다 찾아줌
const filterd = items.filter(item => item[key] === value);
console.log("aaaa");
console.log(filterd);
displayItems(filterd);
}
// main 프로미스 소비자 , json 데이터 받아와 ~
loadItems() // 함수는 데이터를 다 받고 불러줘야 실행됨 🧡
.then(items =>{
displayItems(items);
setEventListerners(items);
})
// .catch(error => {
// console.log(error);
// })
// .finally(() => {
// console.log('프로미스, finally 끝');
// })
data > data.json
{
"items":[
{
"type":"tshirt",
"gender":"남성",
"size":"large",
"color":"pink",
"image":"imgs/pink_t.png"
},
{
"type":"skirt",
"gender":"여성",
"size":"samll",
"color":"yellow",
"image":"imgs/yellow_s.png"
},
{
"type":"pants",
"gender":"남성",
"size":"middle",
"color":"blue",
"image":"imgs/blue_p.png"
},
{
"type":"skirt",
"gender":"여성",
"size":"large",
"color":"pink",
"image":"imgs/pink_s.png"
},
{
"type":"tshirt",
"gender":"남성",
"size":"large",
"color":"yellow",
"image":"imgs/yellow_t.png"
},
{
"type":"pants",
"gender":"여성",
"size":"large",
"color":"blue",
"image":"imgs/blue_p.png"
},
{
"type":"tshirt",
"gender":"남성",
"size":"large",
"color":"blue",
"image":"imgs/blue_t.png"
},
{
"type":"skirt",
"gender":"여성",
"size":"samll",
"color":"yellow",
"image":"imgs/yellow_s.png"
},
{
"type":"pants",
"gender":"남성",
"size":"large",
"color":"yellow",
"image":"imgs/yellow_p.png"
},
{
"type":"skirt",
"gender":"여성",
"size":"samll",
"color":"pink",
"image":"imgs/pink_s.png"
}
]
}
css > style.css
:root {
/* color */
--color-black: #3f454d;
--color-white: #fff;
--color-blue: #3b88c3;
--color-yellow: #fbbe28;
--color-pink: #fd7f84;
--color-light-gray: #dfdfdf;
/* size */
--base-space: 8px;
--size-button: 60px;
--font-size: 14px;
--size-border: 4px;
--size-thumbnail: 45px;
/* animation */
--animation:0.3s;
}
* {
padding:0; margin: 0; box-sizing: border-box;
}
li { list-style: none;}
body {
height: 100vh;
background: var(--color-black);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.logoDiv {
text-align: center;
}
.logo{
cursor: pointer;
transition: transform var(--animation);
}
.logo:hover, .btn:hover {
transform: scale(1.1);
}
.btn {
/* 버튼 배경색 빼기 */
background: transparent;
border: none;
outline: none;
cursor: pointer;
margin-right: var(--font-size);
transition: transform var(--animation);
}
.imgBtn {
width: var(--size-button);
height: var(--size-button);
}
.colorBtn {
font-size: var(--font-size);
padding:calc(var(--base-space) * 2);
border-radius: var(--size-border);
}
.blue {
background-color: var(--color-blue);
}
.yellow {
background-color: var(--color-yellow);
}
.pink {
background-color: var(--color-pink);
}
.buttonDiv {
display: flex;
align-items: center;
}
.items {
width: 100%;
height: 60%;
overflow-y: scroll;
padding-top: var(--base-space);
}
.item {
background-color: var(--color-white);
display: flex;
align-items: center;
padding: var(--base-space);
margin-bottom: var(--base-space);
}
.item_thumbnail {
width: var(--size-thumbnail);
height: var(--size-thumbnail);
}