🎨 mini-shopping mall

kirin.log·2021년 3월 16일
0
post-custom-banner

🪐 logic

  • html 내 logo와 6개의 버튼 레이아웃을 만든다
  • 버튼을 누를 때 보여지는 list들은 ul만 만들고, li는 js로 만든다(비워둔다)
  • json으로 직접 list들의 객체를 만들어 준다 ➡ js에서 fetch함수로 불러온다
  • list를 보여주는 함수, 버튼에 따라 filtering되는 함수 2개를 만들어 주고, promise를 통해 성공했을 경우 함수가 실행되도록 한다.
  • list를 보여주는 함수는 innerHTML을 통해 직접 html태그로 삽입한다.
  • 버튼에 따라 filtering되는 함수는, dataset을 통해 조건문을 걸어준다
🎅 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="index.css" />
        <script src="index.js" defer></script>
    </head>
    <body>
        <header>
            <img src="./img/logo.png" alt="logo" class="logo" />
        </header>
        <nav>
            <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">
                <img src="./img/blue_t.png" alt="tshirt" class="imgBtn" data-key="type" data-value="tshirt" />
            </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>
        </nav>
        <main>
            <div>
                <ul class="items">
                    <!--javascript로 생성할 부분
                       
                    <li class="item">
                        <img src="./img/blue_t.png" alt="tshirt" class="item_thumbnail" />
                        <span class="item_description">male, large</span>
                    </li>-->
                </ul>
            </div>
        </main>
    </body>
</html>
🎅 css

:root {
    /* color */
    --color-black: #3f454d;
    --color-white: #ffffff;
    --color-blue: #3b88c3;
    --color-yellow: #fbbe28;
    --color-pink: #fd7f84;
    --color-light-grey: #dfdfdf;
    /* size */
    --size-button: 60px;
}

* {
    box-sizing: border-box;
}

body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: var(--color-black);
}

.logo {
    cursor: pointer;
    transition: transform 300ms ease;
}

nav {
    display: flex;
    align-items: center;
}

.btn {
    margin-right: 8px;
    background-color: transparent;
    border: none;
    outline: none;
    cursor: pointer;
    transition: transform 300ms ease;
}

.logo:hover,
.btn:hover {
    transform: scale(1.1);
}

.imgBtn {
    width: var(--size-button);
    height: var(--size-button);
}

.colorBtn {
    padding: 16px;
    font-size: 18px;
    border-radius: 5px;
}

.blue {
    background-color: var(--color-blue);
}

.yellow {
    background-color: var(--color-yellow);
}

.pink {
    background-color: var(--color-pink);
}

/* js 생성 list */

.items {
    width: 60vw;
    height: 60vh;
    list-style: none;
    padding-left: 0;
    overflow-y: scroll;
}

.item {
    display: flex;
    align-items: center;
    margin-bottom: 18px;
    padding: 8px;
    background-color: white;
}

.item_thumbnail {
    width: 50px;
    height: 50px;
}

.item_description {
    margin-left: 18px;
    font-size: 18px;
}
🎅 js

"use strict";

// Fetch the items from the JSON file
function loadItems() {
    return fetch("data/data.json")
        .then((response) => response.json()) // 성공이면 json으로 변환하고
        .then((json) => json.items); // json안의 items를 리턴한다
}

// JSON파일을 불러오는데 시간이 걸리기 때문에 promise로 불러온다(비동기)
// promise 사용해주기 (성공할땐 .then  /  실패할땐 .catch)
loadItems()
    .then((items) => {
        // 성공이면, 아래 두 함수를 실행한다
        displayItems(items);  // item 를 보여주는 함수
        setEventListener(items); // filtering 해주는 함수
    })
    // 실패하면, console.log로 출력되도록 한다
    .catch(console.log);

// (1) items(ul) 안에 list들을 넣어주기 위해, 받아온 데이터를 mapping하여 각 li태그로 변환하여 넣어준다
function displayItems(items) {
    const container = document.querySelector(".items");
    container.innerHTML = items.map((item) => createHTMLString(item)).join("");
}

// li태그를 문자열로 변환하는 함수
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>
    `;
}

// (2) 각 버튼들을 클릭하면 eventListener가 작동하도록 하는 함수
function setEventListener(items) {
    const logo = document.querySelector(".logo");
    const btns = document.querySelector("nav");

    // logo 버튼을 클릭하면 모든 리스트가 보이도록
    logo.addEventListener("click", () => displayItems(items));
    // nav 버튼 6개들이 클릭되면 onButtonClick함수가 실행되도록
    btns.addEventListener("click", (e) => onButtonClick(e, items));
}

// nav 버튼 6개들에 대한 filering 해주기
// html에 "data-" 를 지정해준다   >>   data-key, data-value
function onButtonClick(e, items) {
    //console.log(e.target.dataset.key);
    //console.log(e.target.dataset.value);
    const dataset = e.target.dataset;
    const key = dataset.key;
    const value = dataset.value;

    // 필터링 할 정보가 들어있지 않으면 그냥 return하기
    if (key == null || value == null) {
        return;
    }

    // 각 item들에 filter를 적용한다. dataset에 의해 key와 value가 같을 경우만 filter하기
    const filtered = items.filter((item) => item[key] === value);
    // console.log(filtered);

    // 필터링 할 정보가 들어있지 않는 경우를 제외하면(=필터링 할 정보가 들어있으면) displayItems함수를 실행한다
    displayItems(filtered);
}
🎅 data-json

{
    "items": [
        {
            "type": "tshirt",
            "gender": "female",
            "size": "large",
            "color": "pink",
            "image": "img/pink_t.png"
        },
        {
            "type": "pants",
            "gender": "male",
            "size": "small",
            "color": "blue",
            "image": "img/blue_p.png"
        },
        {
            "type": "pants",
            "gender": "male",
            "size": "large",
            "color": "yellow",
            "image": "img/yellow_p.png"
        },
        {
            "type": "skirt",
            "gender": "female",
            "size": "large",
            "color": "yellow",
            "image": "img/yellow_s.png"
        },
        {
            "type": "tshirt",
            "gender": "male",
            "size": "small",
            "color": "pink",
            "image": "img/pink_t.png"
        },
        {
            "type": "skirt",
            "gender": "female",
            "size": "large",
            "color": "blue",
            "image": "img/blue_s.png"
        },
        {
            "type": "tshirt",
            "gender": "male",
            "size": "small",
            "color": "blue",
            "image": "img/blue_t.png"
        },
        {
            "type": "skirt",
            "gender": "female",
            "size": "small",
            "color": "yellow",
            "image": "img/yellow_s.png"
        },
        {
            "type": "tshirt",
            "gender": "female",
            "size": "large",
            "color": "yellow",
            "image": "img/yellow_t.png"
        },
        {
            "type": "tshirt",
            "gender": "female",
            "size": "large",
            "color": "blue",
            "image": "img/blue_t.png"
        },
        {
            "type": "pants",
            "gender": "male",
            "size": "small",
            "color": "pink",
            "image": "img/pink_p.png"
        },
        {
            "type": "skirt",
            "gender": "female",
            "size": "large",
            "color": "pink",
            "image": "img/pink_s.png"
        }
    ]
}
profile
boma91@gmail.com
post-custom-banner

0개의 댓글