Dream Coding 엘리 선생님의 무료 강의, "쇼핑몰 미니게임 클론 코딩 & 코드 리뷰" 을 들으며 간단한 쇼핑몰 사이트를 따라 만들어보려한다.
아예 강의를 보며 똑같이 입력하면 실력이 절대 늘지 않는다는 선생님의 말씀에 따라, 일단 강의에 올려주신 파일을 사용해서 만들어야겠다는 생각이 들었다. 파일에는 로고와 옷 그림, 그리고 index.html 기본 틀만 있는 정도였다.
body는 일단
얼추 아이템의 배치 정도는 금방 할 수 있게 되었다. 물론 반응형으로 배치가 바뀌고 이런건 지금 안했다. 이제 수업을 들어보고 해봐야지....
수업을 들으면서 따라 만들어보았다.
main.js
//JSON파일에서 아이템 Fetch
function loadItems() {
return fetch('data/data.json')
.then(response => response.json())
.then(json => json.items);
}
//items를 리스트에 업데이트
function displayItems(items) {
const container = document.querySelector('.items');
container.innerHTML = items.map(item => creatHTMLString(item)).join('');
}
//data item을 HTML 리스트 아이템으로 만들기
function creatHTMLString(item) {
return `
<li class="item">
<img src="${item.image}" alt="${item.type}" class="item__thumbnail">
<span class="item__description">${item.gender}, ${item.size}</span>
</li>
`;
}
//main
loadItems()
.then((items) => {
displayItems(items);
// setEventListeners(items);
})
.catch(console.log);
function onButtonClick(event, items) {
const dataset = event.target.dataset;
const key = dataset.key;
const value = dataset.value;
if(key == null || value == null) {
return;
}
const filtered = items.filter(item => item[key] === value);
displayItems(filtered)
}
function setEventListeners(items) {
const logo = document.querySelector('.logo')
const buttons = document.querySelector('.buttons')
logo.addEventListener('click', () => displayItems(items))
buttons.addEventListener('click', event => onButtonClick(event, items))
}
다시보니 분홍색 티셔츠 그림이 있어야할 json 데이터에 분홍색 치마 그림을 넣어버렸다...ㅠㅠ
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Online Shopping</title>
<link rel="stylesheet" href="style.css" />
<script src="src/main.js" defer></script>
</head>
<body>
<!-- Logo -->
<img src="img/logo.png" alt="logo" class="logo">
<!-- Buttons -->
<section class="buttons">
<button class="btn"><img src="img/blue_t.png" alt="tshirt" class="imgBtn" data-key="type"
data-value="tshirt"></button>
<button class="btn"><img src="img/blue_p.png" alt="pants" class="imgBtn" data-key="type"
data-value="pants"></button>
<button class="btn"><img src="img/blue_s.png" alt="skirt" class="imgBtn" 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>
</section>
<!-- Items -->
<ul class="items">
</ul>
</body>
</html>
style.css
:root {
/* color */
--color-black: #3f454d;
--color-white: #ffffff;
--color-blue: #3b88c3;
--color-yellow: #fbbe28;
--color-pink: #fd7f84;
--color-light-grey: #dfdfdf;
/* size */
--base-space: 8px;
--size-button: 60px;
--size-border: 4px;
--size-thumbnail: 50px;
--font-size: 18px;
/* animation */
--animation-duration: 300ms;
}
* {
box-sizing: border-box;
}
body {
height: 100vh;
background-color: var(--color-black);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.logo {
cursor: pointer;
transition: transform var(--animation-duration) ease;
}
.btn {
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
transition: transform var(--animation-duration) ease;
margin-right: var(--base-space);
}
.logo:hover,
.btn:hover {
transform: scale(1.1);
}
.buttons {
display: flex;
align-items: center;
}
.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);
}
.items {
width: 60%;
height: 60%;
list-style: none;
padding-left: 0;
overflow-y: scroll;
}
.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);
}
.item__description {
margin-left: var(--base-space);
font-size: var(--font-size);
}
main.js
//JSON파일에서 아이템 Fetch
function loadItems() {
return fetch('data/data.json')
.then(response => response.json())
.then(json => json.items);
}
//items를 리스트에 업데이트
function displayItems(items) {
const container = document.querySelector('.items');
container.innerHTML = items.map(item => creatHTMLString(item)).join('');
}
//data item을 HTML 리스트 아이템으로 만들기
function creatHTMLString(item) {
return `
<li class="item">
<img src="${item.image}" alt="${item.type}" class="item__thumbnail">
<span class="item__description">${item.gender}, ${item.size}</span>
</li>
`;
}
function onButtonClick(event, items) {
const dataset = event.target.dataset;
const key = dataset.key;
const value = dataset.value;
if(key == null || value == null) {
return;
}
const filtered = items.filter(item => item[key] === value);
displayItems(filtered)
}
function setEventListeners(items) {
const logo = document.querySelector('.logo')
const buttons = document.querySelector('.buttons')
logo.addEventListener('click', () => displayItems(items))
buttons.addEventListener('click', event => onButtonClick(event, items))
}
//main
loadItems()
.then((items) => {
displayItems(items);
setEventListeners(items);
})
.catch(console.log);
data.json
{
"items": [
{
"type": "tshirt",
"gender": "female",
"size": "large",
"color": "pink",
"image": "../img/pink_t.png"
},
{
"type": "pants",
"gender": "male",
"size": "small",
"color": "yellow",
"image": "../img/yellow_p.png"
},
{
"type": "skirt",
"gender": "male",
"size": "large",
"color": "blue",
"image": "../img/blue_s.png"
},
{
"type": "tshirt",
"gender": "female",
"size": "small",
"color": "yellow",
"image": "../img/yellow_t.png"
},
{
"type": "skirt",
"gender": "female",
"size": "large",
"color": "pink",
"image": "../img/pink_s.png"
},
{
"type": "pants",
"gender": "female",
"size": "medium",
"color": "blue",
"image": "../img/blue_p.png"
},
{
"type": "tshirt",
"gender": "male",
"size": "small",
"color": "pink",
"image": "../img/pink_s.png"
}
]
}