header hover시 하위 메뉴 보여주기

ahncheer·2024년 8월 12일
0

LWC & LWR

목록 보기
51/52

1. 사용한 방법

* 기능 설명

빨간 영역(Header 상단)에 마우스가 올라가 있는 경우 파란 영역이 보여야 함

파란 영역(Header 하단)위에 마우스가 올라가 있는 경우에도 파랑 영역이 사라지지 않게 함

* 동작 설명

빨간 영역(Header 상단)에 마우스가 올라가 있는 경우 하양 배경에 a 클래스를 추가함. 마우스가 올라가 있지 않다면 a 클래스를 제거함.

파란 영역(Header 하단)위에 마우스가 올라가 있는 경우 하양 배경에 b 클래스를 추가함. 마우스가 올라가 있지 않다면 b 클래스를 제거함.

하양배경에 a, 또는 b class가 추가되어 있는 경우 파랑 배경이 보이도록 함.

2. 코드 작성

2-1. html

<template>
   <div class="cpHeader">
       <!-- 메뉴 상단 부분 -->
       <div class="h-wrap">
           <div class="header-wrap">
               <div class="logo" onclick={goMain}>logo</div>
               <ul class="menu main-menu">
                   <template for:each={menuList} for:item="item" for:index="index">
                   <li key={item.mainLink} data-link={item.mainLink} onclick={goPage}>
                           {item.mainLabel}
                   </li>
                   </template>
               </ul>
               <div class="login">login</div>
           </div>
       </div>

       <!-- 메뉴 하단 부분 -->
       <div class="sub-menu-wrap">
           <div class="sub-menu">
               <ul class="menu">
                   <template for:each={menuList} for:item="item" for:index="index">
                   <li key={item.mainLink}>
                       <div class="sub">
                           <template for:each={item.subMenu} for:item="subItem">
                           <p key={subItem.link} data-link={subItem.link} onclick={goPage}>
                                   {subItem.label}
                           </p>
                           </template>
                       </div>
                   </li>
                   </template>
               </ul>
           </div>            
       </div>
           
       
   </div>
</template>

2-1. js

import { LightningElement, track } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';
import basePathName from '@salesforce/community/basePath';

export default class CpHeader extends NavigationMixin(LightningElement)  {
    // 메뉴
    @track menuList = [
        {
            mainLabel: 'About'
            , mainLink: '/about-us'
            , subMenu: [{ label: 'About us', link: '/about-us' },
            { label: 'Our History', link: '/history' }]
        },
        {
            mainLabel: 'Products'
            , mainLink: '/products'
            , subMenu: [{ label: 'Card Products', link: '/products' }],
        },
        {
            mainLabel: 'Tables'
            , mainLink: '/table/basic-table'
            , subMenu: [{ label: 'Basic Table', link: '/table/basic-table' },
            { label: 'Filter Table', link: '/table/filter-table' },
            { label: 'Canvas', link: '/table/img-download' }]
        },
        {
            mainLabel: 'Support'
            , mainLink: '/support/contact-us'
            , subMenu: [{ label: 'FAQ', link: '/support/faq' },
            { label: 'Contact Us', link: '/support/contact-us' }]
        },
    ];

    renderedCallback() {
        let mainEl = this.template.querySelector('.cpHeader');
        let menuEl = this.template.querySelector('.main-menu');
        let subMenuEl = this.template.querySelector('.sub-menu-wrap');

        // 메뉴 상단에 마우스를 가져다 대었을 때 menu-hover class 추가
        if (menuEl) {
            menuEl.addEventListener('mouseover', () => {
                mainEl.classList.add('menu-hover');
            });
            menuEl.addEventListener('mouseleave', () => {
                setTimeout(() => {
                    mainEl.classList.remove('menu-hover');
                }, 300);
            });
        }

        // 메뉴 하단에 마우스를 가져다 대었을 때 sub-hover class 추가
        if (subMenuEl) {
            subMenuEl.addEventListener('mouseover', () => {
                mainEl.classList.add('sub-hover');
            });
            subMenuEl.addEventListener('mouseleave', () => {
                setTimeout(() => {
                    mainEl.classList.remove('sub-hover');
                }, 300);
            });
        }
    }

    // 각 메뉴를 클릭한 경우 페이지 이동
    goPage(e){
        let link = e.currentTarget.dataset.link;
        console.log('window.location.origin + link + basePathName; : ', window.location.origin + basePathName + link);
        if(link) window.location.href = window.location.origin + basePathName + link;
    }

    // 로고를 클릭한 경우 메인으로 이동
    goMain(){
        console.log('window.location.origin + basePathName; : ', window.location.origin + basePathName);
        window.location.href = window.location.origin + basePathName;
    }

}

2-3. css

.cpHeader{
	width: 100%;
	position: relative;
    z-index: 9999;
}

.logo {
    width: 200px;
    height: 60px;
    background-color: #ddd;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login {
    width: 200px;
    height: 60px;
    text-align: center;
    background-color: #ddd;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* menu-hover, sub-hover */
.menu-hover .sub-menu-wrap, .sub-hover .sub-menu-wrap{
	transform: translateY(100%);
}

/* menu */
.h-wrap{
	background-color: #fff;
	position: relative;
    z-index: 2;
}
.header-wrap {
    position: relative;
    max-width: 1080px;
    width: 100%;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
}
.menu{
    position: relative;
    width: calc(100% - 600px);
	margin: 0 auto;

    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    align-items: center;
    gap: 10px;
}

.menu.main-menu li {
    padding: 8px 16px;
    text-align: center;
    height: 100%;
    width: 100%;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    position: relative;
    cursor: pointer;
}


/* subMenu */
.sub-menu-wrap{
    background-color: #f4f4f4;
	width: 100%;
	position: absolute;
    bottom: 0;
    transform: translateY(0);
    z-index: 1;
	transition: 0.1s ease-out;
}
.sub-menu {
	max-width: 1080px;
    width: 100%;
    margin: 0 auto;
	padding: 10px 0 30px 0;
}
.sub-menu .menu{
	align-items: start;
}
.sub-menu .menu li {
    align-items: flex-start;
}

.sub-menu .menu li .sub p {
    padding: 8px;
	text-align: center;
	cursor: pointer;
}
.sub-menu .menu li .sub p + p{
	margin-top: 10px;
}
.sub-menu .menu li .sub p:hover {
	background-color: #fbfbfb;
    font-weight: bold;
}

2-4. 화면 확인

확인하기 편하도록 각 메뉴 hover시 클릭 영역의 배경색만 바뀌게 해두었는데, 다른 CSS로 하는 것을 추천합니다.

profile
개인 공부 기록용.

0개의 댓글