쇼핑몰 미니게임 클론 코딩(Dream Coding by 엘리)
Dream Coding 엘리 선생님의 무료 강의, "쇼핑몰 미니게임 클론 코딩 & 코드 리뷰" 을 들으며 간단한 쇼핑몰 사이트를 따라 만들어보려한다.
아예 강의를 보며 똑같이 입력하면 실력이 절대 늘지 않는다는 선생님의 말씀에 따라, 일단 강의에 올려주신 파일을 사용해서 만들어야겠다는 생각이 들었다. 파일에는 로고와 옷 그림, 그리고 index.html 기본 틀만 있는 정도였다.
body는 일단
- 맨 위에 log 박스
 - 버튼과 옷이 그려져있는 중간부분인 action 박스
 - 맨 밑에 있는 list
 
얼추 아이템의 배치 정도는 금방 할 수 있게 되었다. 물론 반응형으로 배치가 바뀌고 이런건 지금 안했다. 이제 수업을 들어보고 해봐야지....
수업을 들으면서 따라 만들어보았다.

HTML, CSS에서 기억해야할 내용!
- alt는 이미지가 보이지 않을때 대신 보이는 글자!
 - 아이템의 class="a b c"이면, a, b, c의 css를 중첩해서 적용!
 - 공통으로 사용되는 색깔, 크기, 애니메이션 등은 css파일의 :root{}에 변수화하고 사용!
 - width와 height를 일정 px로 지정하기 X! %나 vh를 사용하여 비율을 유지!
 
JavaScript에서 기억해야할 내용!
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);
- 어떠한 형태로 동작이 될것인지 골격부터 설계하기!(//main)
  
- 아이템 데이터 호출에 성공한다.
    
- 데이터를 출력한다.
 - 데이터와 관련된 이벤트를 설정한다.
 
 - 데이터 호출에 실패할 경우, 에러처리를 한다.
 
 - 아이템 데이터 호출에 성공한다.
    
 - 함수를 만들면서 계속 결과가 나오는지 확인한다(콘솔을 통해 함수 동작 및 json 출력 확인)
 - json 데이터를 html에 출력할 수 있도록 변환한다.
    
- document.querySelector로 json 데이터 변수 생성(const container)
 - json을 html형태로 return하는 함수 생성(function createHTMLString(item))
 - map, join로 container.innerHTML에 하나의 문자열로 담아 업데이트
 
 
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))
}
- 각 버튼의 이벤트 설정하는 함수 만들기(setEventListeners)
  
- logo와 buttons 변수 선언
 - addEventListener를 사용하여 각 변수가 'click'되었을때의 이벤트를 설정
      
- logo ==> displayItems(로고를 클릭했을때 모든 아이템 보이기)
 - buttons ==> onButtonClick(클릭한 버튼에 해당하는 아이템만 보이기)
 
 - 각 버튼의 value에 해당하는 값을 보여주는 onButtonClick 함수 선언
      
- dataset, key, value 변수 선언
 - key와 value가 null인 경우 함수 종료
 - filter를 사용하여 클릭한 아이템의 key와 일치하는 value만 걸러내기(filtered 변수)
 - displayItem함수에 filtered 인자값으로 넣어서 출력
 
 
 

다시보니 분홍색 티셔츠 그림이 있어야할 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"
        }
    ]
}
                Author And Source
이 문제에 관하여(쇼핑몰 미니게임 클론 코딩(Dream Coding by 엘리)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@minbrother/쇼핑몰-미니게임-클론-코딩Dream-Coding-by-엘리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)