쇼핑몰 웹사이트 만들어보기- 카테고리 꾸미기

Shiba·2024년 3월 23일
0

프로젝트 및 일기

목록 보기
3/29
post-thumbnail

지난 시간엔 요즈음 쇼핑몰에 있는 비동기 카테고리를 구현해보았다. 이번 시가에는 멋없는 비동기 카테고리를 예쁘게 꾸미고, 가능하다면 추가하려고 했던 다른 요소들도 만들어보도록 하자.

시작하기 전에, 만든 것을 이리저리 만지다보니 카테고리에서 세부 카테고리 부분에서 버그를 발견했었다.. 카테고리의 갯수가 많아지면 박스 바깥으로 카테고리가 삐져나가던 버그였다. 이를 수정하기 위해 category-menu 태그에 들어오는 요소를 정렬할 수 있도록

display: flex; 
flex-wrap: wrap;

를 추가하였고, 또한 창 크기를 줄일 경우, 카테고리가 서로 띄어지지않고 붙어나오는 현상이 있었다. 이를 수정하기 위해 본래는 %로 정해두었던 너비와 높이를 고정된 픽셀값으로 바꾸었다. 그리고 카테고리 이름이 출력되도록 하는 ajaxCategory-item 태그를 블럭으로 바꾸어 카테고리 이름끼리 서로 분리되도록 하였다.

.ajaxCategory-item{
    flex: 1 0 200px;
    display: block;
}

이제 카테고리를 꾸며보자. 꾸미는데에는 지마켓을 클론코딩해보기로 했다.

지마켓에서 개발자도구를 통해 코드를 열고, 그에 해당하는 css코드를 찾아냈다.

해당코드를 사용하여 카테고리를 가볍게 꾸며보자


다음은 지마켓의 css 코드를 살짝 변경하여 꾸며본 카테고리이다. 하지만 이전에 고쳤던 버그가 다시 발생했다. 아무래도 코드에 존재하는 padding때문에 글자가 서로 띄어지면서 해당 버그가 다시 발생한거 같다. 그렇다고 padding을 줄이는 것은 결국 추후에 세부 카테고리의 종류가 많아지면 생겨나게되므로 이번기회에 제대로 고쳐보도록 하자.

가장 먼저 오류를 해결하기 위해 한건 역시 chatGPT한테 물어보는 것이였다. (주변에 프론트엔드를 하는 사람이 있었다면...)


지피티가 2개중에 더 선호하는 방법을 선택하라고 한다. 코드를 보니 둘다 원리는 같은 것 같았다. 세부 카테고리 태그를 inline-block으로 선언해 가로로 배열하도록 하되, 혹시나 카테고리가 너무 많아 넘어간다면 스크롤을 넣으라는 것이다.
하지만, 그정도로 많은 카테고리가 있으면 오히려 제품의 카테고리를 눈으로 찾는거 보다 직접 제품을 검색해서 찾는게 더욱 빠를 것 같으니 여기서 스크롤은 빼고 inline-block을 통해 해결하도록 하자.

inline-block 선언을 통해 다음과 같이 버그를 해결하였다.

어느정도 카테고리도 만들어진것 같으니 이제 다른 요소들도 만들어보도록하자.

이번에 만들어볼 것은 검색창이다. 검색창은 지금까지 html을 만져보면서 예측해보자면 뼈대자체는 input태그를 통해 만들었지만 이것을 js를 이용하여 검색어를 변수로 날려보낼 수 있고, 이것을 스프링이 데이터베이스와 통신하여 원하는 결과를 찾아주는 시스템이 아닐까 생각한다.

chatGPT를 통해 기본적인 뼈대를 만들면서 생각해보자

<!--gpt가 준 코드-->
 <form id="searchForm">
            <input type="text" id="searchInput" placeholder="검색어를 입력하세요">
            <button type="submit">검색</button>
 </form>

이 코드를 보면서 html을 제대로 알지 못하였기때문에 'input태그에 있는 텍스트를 전송버튼이나 엔터를 쳐서 보내는 것이라면 input태그의 id를 통해 데이터를 전송하면 되지 않나, 왜 굳이 form태그를 굳이 써서 보내는걸까?' 가 궁금해져서 gpt에게 물어보았다.

간단히 요약하자면 서버로 전송하려는 데이터의 일관성을 유지하면서도, 개발자,사용자에 대한 접근성을 높이기위해서 사용하는 것 같다.

이제 js 코드를 만들고 간단히 웹을 꾸며 홈화면을 완성해보자. 뼈대는 다음시간부터 작성해보도록하자

작성중에 검색버튼을 위치를 맞추기 위해 margin-top을 이용하여 밑으로 내렸더니 검색창까지 같이 움직이는 현상이 발생했다. gpt한테 물어보니 margin collapse 현상이 발생할 수 있다고한다.

여기서 Margin collapse란 뭘까?

Margin collapse는 인접한 블록 레벨 요소의 margin이 합쳐지는 현상을 말합니다. 그래서 .search_button의 margin-top이 .search_input의 margin-top에 영향을 줄 수 있습니다.


이를 방지하려면 .search_button의 margin-top을 조정하는 대신, padding 또는 border를 사용하여 요소 사이의 공간을 만들 수 있습니다. 혹은 둘을 감싸는 외부 컨테이너를 만들고, 해당 컨테이너의 padding을 조정하여 요소들 사이의 간격을 조절할 수도 있습니다.

라고 한다. 즉 margin-top을 사용하되, 요소가 같이 딸려내려가지않도록 padding을 통해 요소사이의 거리를 띄우라는 것이다.

하지만, padding으로 거리를 벌려도 같은현상이 발생했다. 그래서 어쩔수없이 position속성에서 absolute를 사용하여 직접 위치를 조정하였다...

다음은 완성된(일단은?) 쇼핑몰의 홈페이지이다

+ 여담: 지마켓을 뜯어보고 내가 gpt와 짜집기한 코드를 비교해보니 부족한 점이 참 많았다. 일단 처음 비동기 카테고리를 만들때는 카테고리 태그 안에 세부카테고리가 있지않고, 같은 카테고리 박스 태그안에 존재하고 있었다. 이렇게 나두면 추후에 꼬일 수도 있을 것 같아 여러 시행착오를 거쳐 지마켓과 같이 큰 카테고리 안에 세부 카테고리가 나오게 하였다.
처음에는 마우스가 들어올 시, 해당 정보를 끌어와서 호출하고 다른 카테고리를 선택하거나 영역을 벗어나면 나가는 형태였다. 지금은 미리 정보를 다 큰 카테고리의 자식태그로 저장을 해두고 이를 display속성을 inline-block으로 변경하여 호출되게하였다.

위의 문제를 해결해내니 다시 카테고리 관련해서 세부카테고리가 정해진 범위를 넘어서는 버그가 생겼다. 이는 지마켓에서 해결책을 찾았다.
지마켓의 코드는 해당 카테고리에 마우스가 올려질 시, id값이 바뀌면서 해당 카테고리의 세부카테고리 display속성이 바뀌도록 설계가 되어있었다. 이를 완전히 같은 원리로 id값을 바꾸어서 해당 addEventListener내에서 해결되도록 하였다.

function renderCategories(categories) {
        // 카테고리 메뉴 요소 가져오기
        category_div.classList.add("category_all_layer");

        // 카테고리 메뉴와 세부 카테고리 메뉴를 부모 요소에 추가
        category_div.appendChild(category_1depth);
        category_box.appendChild(category_div);
        console.log(categories);
        // 카테고리 데이터를 동적으로 HTML에 추가
        categories.forEach(ajaxCategory => {
            const categoryItem = document.createElement("li");
            categoryItem.textContent = JSON.stringify(ajaxCategory.name).replace(/"/g, '');
            categoryItem.classList.add("category_item");
			
          	//세부 카테고리 태그
            const category_2depth = document.createElement("div");
            category_2depth.id = "category_2depth";
            categoryItem.appendChild(category_2depth);
			
          	//세부 카테고리 정보 미리 받아두기
            ajaxCategory.detail.forEach(detail => {
                const detailItem = document.createElement("li");
                detailItem.textContent = detail;
                detailItem.classList.add("detail_item");
                category_2depth.appendChild(detailItem);

                detailItem.addEventListener("click", () => {
                    // 사용자가 카테고리를 클릭했을 때 실행될 함수 호출
                    redirectSearchResult(ajaxCategory.detail);
                });
            });

            // 마우스가 카테고리에 올라갔을 때 세부 카테고리 표시
            categoryItem.addEventListener("mouseenter", () => {
                //마우스가 올려진 카테고리의 id를 변경
              	categoryItem.id = "category_item_active";
              	
              	//해당 카테고리에 마우스가 들어왔으니 실행
                categoryItem.addEventListener("mouseenter", () => {
                    category_2depth.style.display = "inline-block";
                });
              	//다른 카테고리에 마우스가 올려지는 경우
                categoryItem.addEventListener("mouseleave", () => {
                    category_2depth.style.display = "none";
                    categoryItem.id = "category_item";
                });
            });

            // 마우스가 카테고리에서 벗어났을 때 세부 카테고리 숨기기
            category_box.addEventListener("mouseleave", () => {
                category_2depth.style.display = "none";
            });

해당 코드에서 categoryItem은 각각 category_2depth를 자식으로 가지고 있으므로 큰 카테고리부분에서 마우스를 옮겨 세부카테고리로 오더라도 해당 display속성이 none이 되지 않는다.

또한, gpt가 생성해낸 코드를 짜집기해서 그런지 변수명이 통일이 되어있지않았다. 예를 들면 어떤 변수는 변수명에-를 쓰는데 다른 변수는 _를 쓰는 경우가 있었다. 이를 _로 고정하기로 하고 하나씩 모두 수정하였다.

첫 프로젝트라 그런지 무언가 설계가 체계적이지 않으며 맨땅에 헤딩하듯이 정보를 습득하여 기능을 구현해내고 있는 것 같다. 조금 더 체계적으로 코드를 짤 수 있도록 많은 지식을 습득하고 노력해야겠다.

profile
모르는 것 정리하기

0개의 댓글