자바스크립트

[JavaScript] 메뉴 클릭할 때마다 해당 리스트 필터링

코딩하는둥이 2025. 2. 22. 15:12

메뉴 클릭할 때마다 해당 리스트가 보이게 된다. 

 

 

먼저 리스트를 만들어줍니다.

const menu = [
    {
        id: 1,
        title: "pancakes",
        category: "breakfast",
        price: 3000,
        img: "./images/item-1.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 2,
        title: "diner",
        category: "lunch",
        price: 1000,
        img: "./images/item-2.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 3,
        title: "milkshake",
        category: "shakes",
        price: 2000,
        img: "./images/item-3.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 4,
        title: "country delight",
        category: "breakfast",
        price: 8000,
        img: "./images/item-4.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 5,
        title: "egg attack",
        category: "lunch",
        price: 3000,
        img: "./images/item-5.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 6,
        title: "oreo dream",
        category: "shakes",
        price: 7000,
        img: "./images/item-6.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 7,
        title: "bacon overflow",
        category: "breakfast",
        price: 3000,
        img: "./images/item-7.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 8,
        title: "american classic",
        category: "lunch",
        price: 4000,
        img: "./images/item-8.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 9,
        title: "quarantine buddy",
        category: "shakes",
        price: 1000,
        img: "./images/item-9.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
    {
        id: 10,
        title: "bison steak",
        category: "dinner",
        price: 2000,
        img: "./images/item-10.jpeg",
        desc: `Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nihil repellendus repellat exercitationem commodi! Cumque perferendis molestias iste aliquam, nulla, qui reprehenderit ea, sequi eveniet dolorem praesentium aliquid aperiam vel libero!`,
    },
];

 

메뉴 버튼과 메뉴 리스트 부분의 요소를 불러옵니다.

const sectionCenterEl = document.querySelector(".section-center");
const btnContainerEl = document.querySelector(".btn-container");

 

메뉴 리스트에 있는 값을 가져오기 위해서 동적으로 메뉴 가져오기 위한 함수를 만듭니다.

function displayMenuButtons() {
  
}

 

객체에 있는 카테고리를 가지고 와서 배열로 만듭니다. 

function displayMenuButtons() {
   // reduce로 순회하면서 cur의 categories에서 객체가 없으면 acc에 누적
    const categories = menu.reduce( (acc, cur) =>{
        if(!acc.inclues(cur.categories)){
            acc.push[cur.categorie];
        }
    },['all'])
    
    // 이제 동적으로 바꾸기 위해서 카테고리을 순회하면서 data-id값을 return 해주고 join 해줍니다.
    const categoryBtns = categories
        .map((category) => {
            return `<button type="button" class="filter-btn" data-id=${category}>
        ${category}
      </button>`
        })
        .join("");
   // btnContainerEl에 categoryBtns을 넣어줍니다.
    btnContainerEl.innerHTML = categoryBtns;
}

 

그러면 데이터가 추가해도 동적으로 카테고리가 늘어납니다. 

 

이제 버튼을 클릭할 때마다 해당 리스트가 보이도록 만들겠습니다.

 

먼저 메뉴 버튼을 다 가지고 옵니다.

    const filtersBtns = btnContainerEl.querySelectorAll(".filter-btn");

 

선택한 카테고리와 일치하는 것만 필터링해줍니다. 

filterBtns는 collection이기 때문에 배열로 순회하는 메소드를 사용할 수 없어서 forEach를 사용합니다.

    filtersBtns.forEach((btn) => {
    	// 메뉴를 클릭했을 때 클릭한 객체을 이벤트로 가지고 오고 
        btn.addEventListener('click', (e) => {
         // 메뉴에 있는 data-id의 값들 을 category 안에 넣어줍니다. 
            const category = e.currentTarget.dataset.id;
            // menu 배열에서 선택된 카테고리와 일치하는 아이켐만 필터링합니다.
            const menuCategory = menu.filter((menuItem) => {
                if (menuItem.category === category) {
                    return menuItem;
                }
            })
            
            if (category === 'all') {
                displayMenuItems(menu); // 모든 요소를 보여줍니다.
            } else {
                displayMenuItems(menuCategory); // 각 카테고리 리스트만 보여줍니다.
            }
        })
    })

 

이제 카테고리 별로 리스트가 보여지도록 함수를 만들어 줍니다. 

// menuItems는 각 카테고리 리스트가 배열로 들어가 있습니다.
function displayMenuItems(menuItems) {
    // 이제 동적으로 바꾸기 위해서 카테고리 리스트를 순회하면서 data-id값을 return 해주고 join 해줍니다.
    let displayMenu = menuItems.map((item) => {
        return `<article class="menu-item">
        <img src=${item.img} alt=${item.title} class="photo" />
        <div class="item-info">
            <div class="header">
                <h4>${item.title}</h4>
                <h4 class="price">${item.price}원</h4>
            </div>
            <p class="item-text">
                ${item.desc}
            </p>
        </div>
    </article>`
    })
    displayMenu = displayMenu.join("");
    
 
   // btnContainerEl에 displayMenu을 넣어줍니다.
    sectionCenterEl.innerHTML = displayMenu;
}

 

윈도우에서 displayMenuButtons(), displayMenuItems(menu)이 로드 되었을 때 보여지도록 했습니다. 

window.addEventListener('DOMContentLoaded', () => {
    displayMenuButtons();
    displayMenuItems(menu);
})

 

그러면!! 카테고리를 클릭할 때마다 해당 카테고리만 필터링하는 웹페이지 개발했습니다!!