미니 쇼핑몰 게임 만들어 보기

seul_velog·2021년 12월 27일
0

강의를 보고 JSON을 활용한 간단한 쇼핑몰을 만들어 보며 정리한 것들이다.

✍️ 작성메모

HTML + CSS

1) CSS 파일에서 공통적으로 사용되는 속성값들은 변수로 정의하기

  • 간편하게 유지보수하기 좋다.
 :root {
  /* color */
  --color-black: #3f454d;
  --color-white: #ffffff;
  --color-blue: #3b88c3;
  --color-yellow: #fbbe28;
  --color-pink: #fd7f84;
  --color-light-grey: #dfdfdf;

  /* size */
  --size-space: 8px;
  --size-button: 60px;
  --size-font: 18px;
  --size-border: 4px;
  --size-thumbnail: 50px;

  /* annimation */
  --animation-duration: 300ms;
}

2) HTML 파일에서 퍼스널 프로퍼티 적용시키기




JSON

{
    "items": [
      {
        "type": "tshirt", // 여기서 key는 type, value는 tshirt이다.
        "gender": "female",
        "size": "large",
        "color": "pink",
        "image": "../img/pink_t.png"
      },
      {
        "type": "pants",
        "gender": "male",
        "size": "large",
        "color": "blue",
        "image": "../img/blue_p.png"
      },
      {...} // 모든 아이템 항목들을 작성
   ]
}

1) Data 보관하기

  • (1) HTML에 데이터를 넣기
    : 동적 처리를 할 때, UI적 요소인 HTML안에 데이터와 HTML요소가 함께 섞인 것은 좋지 않다. 그러므로 목록의 아이템을 따로 추출해서 보관하자.

  • (2) JavaScript에 데이터를 넣기
    : js는 어플리케이션의 비즈니스 로직(코드)을 담당하는 곳이므로, 코드와 데이터가 함께 보관되는 것은 피하는 것이 좋다.

  • ▶ 데이터는 데이터를 보관할 수 있는 특별한 장소에 보관하는 것이 좋다.(ex. file, database, back-end서비스 등) 여기서는 data라는 폴더안에 json파일을 이용해서 보관했다.


2) JSON 파일에 데이터 정의하기

  • "items"는 배열이고, 배열 안에는 item들이 들어있다. item은 다시 오브젝트이기 때문에 key와 value로 구성된다.

  • 오브젝트 안에는 해당하는 모든 관련 자료를 묶어서 담아야 한다. 즉, 아이템에 관련된 이미지(경로지정)까지도 포함해서 넣는다.

  • 개발툴-네트워크를 통해서 페이지로딩시 어떤 것들이 다운받아지는지 알 수 있다. data폴더-json파일에 데이터를 정의 하였으므로 다운로드가 되어있지 않은 상태이다.




JavaScript

1. main호출 작성하기 (구현하기 전에 큰 틀 짜기)

loadItems()
.then(items => { 
    displayItems(items); 
    setEventListeners(items); 
})
.catch(console.log) 
  • loadItems()
    : data.json의 아이템을 읽어와서 아이템을 전달해주는 함수, 프로미스를 리턴한다.

  • .then(items => {})
    : 프로미스가 잘 되면 아이템을 받아온다.

  • displayItems(items);
    : 받아온 아이템을 html에 보여주는 함수이다.

  • setEventListeners(items);
    : 받아온 아이템과 이벤트리스너를 통해서 버튼 클릭 시 필터링을 해주는 함수이다.

  • .catch(console.log)
    : 프로미스가 잘 안되면 콘솔 출력을 하기로 한다.



2. JSON 파일로부터 아이템을 동적으로 받아오기

function loadItems(){ 
    return fetch('data/data.json') 
    .then(response => response.json())
    .then(json => json.items);
}
  • fetch 를 이용해서 데이터를 받아온 다음, 받은 데이터가 성공적이면 JSON으로 변환하고, JSON안에있는 items 를 리턴하는 함수이다.

  • 브라우저 API 중 하나인 fetch

    • 해당하는 파일의 경로나 URL을 지정하면 네트워크를 통해서 데이터를 받아올 수 있다.
    • '' 문자열로 전달하지 않아서 오류가 났었다. 유의하자.🥲
    • Fetch는 네트워크 요청과 응답에 관련된 일반적인 Request & Response Object를 제공한다.
    • fecth 는 데이터를 성공적으로 받아오면 response라는 오브젝트를 전달해준다.
  • 개발툴-네트워크를 통해서 JSON이 다운된 것을 확인할 수 있게 되었다.

  • response.json()
    : response 오브젝트가 가지고 있는 json()이라는 API를 이용한다.
    response body를 오브젝트로 변환 → 콘솔로 출력하면 data.json에 정의한 아이템들이 출력된다.



3. 받아온 아이템으로 목록 업데이트하기

function displayItems(items){ 
    const container = document.querySelector('.items'); 
    container.innerHTML = items.map(item => createHTMLString(item)).join('');
}


// 주어진 아이템에서 HTML 목록 만들기
function createHTMLString(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>
    `;
}
  • items 인자를 받아오고 이 데이터를 HTML요소로 변환해서 페이지에 표기되도록 하는 함수이다.

  • document.querySelector 를 이용, 컨테이너 요소.items 를 정의한다. (여기에서는 부모컨테이너안에 추가해야 하므로)

  • element.innerHTML
    : element 안의 HTML이나 XML을 가져온다.

  • map() & join() ▶ 배열메소드(2)
    : 받아온 itemsmap() 을 사용해서 li 그룹으로 만들어서 컨테이너에 추가하고, 문자열의 배열을 join() 을 이용해서 한 가지의 문자열로 병합한다.

  • createHTMLString
    : 각각 아이템을 받아와서 함수를 이용, 아이템을li 태그(요소 문자열)로 만들어 주도록 한다.

  • template string
    : 문자열, 변수, 코드, 등을 중간중간 넣어 쓸 수 있는 문자열 템플릿의 장점을 활용하자.



4. 받아온 아이템과 이벤트리스너를 통해서 버튼 클릭 시 아이템 필터링하기

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)); 
}


// 버튼이 클릭 되었을 때 처리되는 함수
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);
}
  • items 를 전달받아서 버튼클릭동작을 정의하는 함수이다.

  • document.querySelector 를 통해서 로고와 버튼을 정의한다.

  • 버튼이 들어있는 컨테이너 자체에 이벤트 리스너를 등록 => 이벤트 위임 이라고 한다. (각각에 이벤트 리스너를 등록하는 것보다 컨테이너 하나에 등록함으로써 한곳에서 핸들링 할 수 있도록 만들 수 있다.)

  • logo 가 선택되면 모든 아이템들이 보여지도록 설정한다.

  • buttons 가 클릭되면 이벤트가 발생할 수 있도록 해주고, 아이템도 전달한다.

  • 이벤트 처리 함수는 on~~ 식으로 명명하면 구분하고 알아보기 좋다.

  • items 에 있는 배열에 filter() 를 이용 → item 이라는 오브젝트 안에 [key] 에 해당하는 값이 value 와 같은 것들만 필터링 해서 displayItems 로 전달한다.




✍️ 자세히 이해하기

1) JSON 파일로부터 아이템을 동적으로 받아오기 파트

  • 코드 줄마다 콘솔창을 확인하면서 어떻게 JSON으로부터 원하는 데이터를 받아오는지 알아보았다.
  • 궁금해서 임의의 이름으로도 작동이 잘 되는지 확인해 보았다.
function loadItems(){
    return fetch('/data/myData.json')
    // .then(a => console.log(a)) fetch를 통해 받아온 데이터 확인
    .then(a => a.json())
    // .then(b => console.log(b)) .json()을 통해 받아온 데이터 확인
    .then(b => b.Jitems)
    // .then(c => console.log(c)) Jitems의 전체 배열 확인
}
  • .then(a => console.log(a))
    : fetch 를 통해 받아온 데이터 확인 ▼
    -> body와 headers, http의코드 (status)가 성공했는지 실패했는지, fecth가 이용한 url등을 볼 수 있다. 여기서 우리가 원하는 데이터는 body 안에 있다.

  • .then(b => console.log(b))
    : .json()을 통해 받아온 JSON파일 내부의 배열 확인 ▼

  • .then(c => console.log(c))
    : JSON파일 내부의 .Jitems 배열 확인 ▼



2) 받아온 아이템으로 목록 업데이트하기 파트

  • 코드 줄마다 콘솔창을 확인하면서 어떻게 JSON으로부터 받아온 데이터를 HTML에 업데이트 하는지 알아보았다.
  • 임의의 이름으로도 작동이 잘 되는지 확인해 보았다.
function displayItems(i1){
    const container = document.querySelector('.myItems')
    container.innerHTML = i1.map(i2 => createHTMLString(i2)).join('');
}
function createHTMLString(i3){  // li문자열 배열로 변환하기
    return`
    <li class="item">
        <img src="${i3.image}" alt="${i3.type}" class="item__thumbnail">
        <span class="item__description">${i3.gender}, ${i3.size}</span>
    </li>
    `
}
  • container.innerHTML = i1; console.log(container.innerHTML);
    : container에 .innerHTML 적용할 경우 ▼

  • container.innerHTML = i1.map(i2 => createHTMLString(i2)); console.log(container.innerHTML);
    : map() 메소드를 적용할 경우 ▼

  • container.innerHTML = i1.map(i2 => createHTMLString(i2)).join(''); console.log(container.innerHTML);
    : 구분자를 넣은 join('') 메소드를 적용할 경우 ▼ (만약 구분자에 아무것도 넣지 않으면 , 로 구분되어 이전 단계와 똑같이 출력되는 것을 알 수 있었다.)



3) 버튼 클릭 시 아이템 필터링하기 파트

  • 코드 줄마다 콘솔창을 확인하면서 어떻게 필터처리가 되는지 알아보았다.
  • 임의의 이름으로도 작동이 잘 되는지 확인해 보았다.
function setEventListeners(i1){
    const logo = document.querySelector('.logo'); 
    const Btn = document.querySelector('.buttons');

    logo.addEventListener('click', () => displayItems(i1));
    Btn.addEventListener('click', e => onButtonClick(e, i1));
}
function onButtonClick(e1, i2){
    const data = e1.target.dataset;
    const key = data.key;
    const value = data.value;

    if(key == null || value == null){
        return;
    }

    const filtered = i2.filter(i3 => i3[key] === value);
    displayItems(filtered);
}
  • addEventListener()에서 클릭시 호출되는 이벤트 확인 ▼
function onButtonClick(e1, i2){
  const data = e1;
  console.log(data);
};

  • 이벤트 내 target 확인 ▼
function onButtonClick(e1, i2){
  const data = e1.target;
  console.log(data);
};

  • 이벤트 내 target 내 dataset 확인 ▼
function onButtonClick(e1, i2){
  const data = e1.target.dataset;
  console.log(data);
};

  • dataset 내 key와 value 확인 ▼
  • undefined 출력은 if 문으로 제어해 주었다.
function onButtonClick(e1, i2){
    const data = e1.target.dataset;
    const key = data.key;
    const value = data.value;
    console.log(key, value);
};

  • 가져온 아이템 확인 & 필터링 확인 ▼
    const filtered = i2.filter(i3 => i3[key] === value);
    displayItems(filtered);


4) 선택한 버튼과 각각의 배열이 서로 매칭될 수 있도록 작동되는 부분(아이템 필터링)

// HTML 커스텀 프로퍼티
data-key="type" data-value="pants"
data-key="type" data-value="skirt"
data-key="type" data-value="tshirt"
data-key="color" data-value="blue"
data-key="color" data-value="yellow"
data-key="color" data-value="pink"

// js
function onButtonClick(e1, i2){
    const data = e1.target.dataset;
    const key = data.key // type과 color 두가지
    const value = data.value; // skirt, pants, tshirt & pink, blue, yellow

    const filtered = i2.filter(i3 => i3[key] === value);
    displayItems(filtered); // 화면에 전달
  • 데이터속성 사용하기 data- HTML문법
  • i3은 JSON에서 가져온 아이템 배열 오브젝트이다. 이곳에 HTML에서 커스텀 프로퍼티로 지정했던 key 와 value를 그대로 가져와서 단어를 대입 시키는 개념이다. 여기서 해맸다..😓
  • 즉 JSON에서 가져온 아이템 배열에 필터링의 방법으로써 → HTML 커스텀 프로퍼티에 접근 가능한 event.target.dataset.keyevent.target.dataset.value 를 이용한다.




reference)
dream_coding

profile
기억보단 기록을 ✨

0개의 댓글