본문 바로가기
Tutorial/WebD

2023년 웹디자인 기능사 메뉴 : M-2

by @webstoryboy 2023. 5. 9.
Tutorial/webd

2023년 웹디자인 기능사 메뉴 : M-2

by @webs 2023. 05. 01.
22
웹디자인 기능사 메뉴 유형 : M-2
난이도 중급

소개

안녕하세요! 웹스토리보이입니다. 이번에는 가로 메뉴 유형 2번째 시간이 되겠습니다. 미리보기 버튼을 통해 완성할 스크립트를 확인해보세요! 두번째 메뉴는 첫번째와 다르게 전체 서브메뉴가 나오는 구조입니다. 첫번째는 해당 메뉴만 나오지만 두번째는 전체 서브 메뉴가 나오는 구조라 스크립트 상의 차이점은 별거 없습니다. 우선 시험장에서 당황하지 않고 작업하려면 CSS부터 완벽하게 하고 넘어가야 합니다. 그럼 시작해보겠습니다. 렛츠기릿🥹


1. 구조 잡기

미리보기 화면을 확인해 보시면 메뉴에 마우스를 오버하면 서브 메뉴가 나오는 구조입니다. 우선 이 유형을 만들어 보기 전에 A-1 레이아웃 유형의 소스를 가져와서 메뉴 위치와 CSS를 먼저 작업하겠습니다. 스크립트를 작업하기 전에 CSS를 먼저 셋팅하는 것이 가장 중요합니다. 레이아웃을 공부를 하지 않았다면 레이아웃 유형을 꼭 공부하고 오셔야 합니다.

<body>
    <div id="wrap">
        <div id="header">
            <div class="logo"></div>
            <nav class="nav"></nav>
        </div>
        <!-- //header -->

        <div id="slider">
        </div>
        <!-- //slider -->

        <div id="contents">
            <div class="content1"></div>
            <div class="content2"></div>
            <div class="content3"></div>
        </div>
        <!-- //contents -->

        <div id="footer">
            <div class="footer1"></div>
            <div class="footer2"></div>
            <div class="footer3"></div>
        </div>
        <!-- //footer -->
    </div>
    <!-- //wrap -->
</body>
* {
    margin: 0;
    padding: 0;
}
li {
    list-style: none;
}
a {
    text-decoration: none;
    color: #000;
}
#wrap {
    width: 1200px;
    margin: 0 auto;
}
#header {
    width: 100%;
    display: flex;
}
#header .logo {
    width: 20%;
    height: 100px;
    background-color: #efefef;
}
#header .nav {
    width: 80%;
    background-color: #e3e3e3;
}
#slider {
    width: 100%;
    height: 300px;
    background-color: #d9d9d9;
}
#contents {
    width: 100%;
    display: flex;
}
#contents .content1 {
    width: 33.3333%;
    height: 200px;
    background-color: #d1d1d1;
}
#contents .content2 {
    width: 33.3333%;
    height: 200px;
    background-color: #c7c7c7;
}
#contents .content3 {
    width: 33.3333%;
    height: 200px;
    background-color: #bcbcbc;
}
#footer {
    width: 100%;
    display: flex;
}
#footer .footer1 {
    width: 20%;
    height: 100px;
    background-color: #b1b1b1;
}
#footer .footer2 {
    width: 60%;
    height: 100px;
    background-color: #a3a3a3;
}
#footer .footer3 {
    width: 20%;
    height: 100px;
    background-color: #9d9d9d;
}

여기까지 셋팅이 완료되었다면, 메뉴 레이아웃을 작업해보겠습니다. 메뉴 레이아웃은 li안에 li가 들어간 구조입니다. 이렇게 작업하면 구조가 깨지기 때문에 두번째 ulposition: absolute를 이용하여 절대적인 위치값을 설정하였고, 부모 박스 li 속성에 position: relative;를 설정하였습니다. 또한 li 안에 li가 있는 구조이기 때문에 >를 사용하여 바로 밑에 있는 자식만 선택하도록 설정하였습니다. 만약 >가 없다면 자식에 자식도 선택이 되어서 코드를 짜는데 불편하기 때문에 >를 설정하였습니다.

<nav class="nav">
    <ul>
        <li>
            <a href="#">메뉴1</a>
            <ul class="submenu">
                <li><a href="#">서브메뉴1-1</a></li>
                <li><a href="#">서브메뉴1-2</a></li>
                <li><a href="#">서브메뉴1-3</a></li>
                <li><a href="#">서브메뉴1-4</a></li>
            </ul>
        </li>
        <li>
            <a href="#">메뉴2</a>
            <ul class="submenu">
                <li><a href="#">서브메뉴2-1</a></li>
                <li><a href="#">서브메뉴2-2</a></li>
                <li><a href="#">서브메뉴2-3</a></li>
                <li><a href="#">서브메뉴2-4</a></li>
            </ul>
        </li>
        <li>
            <a href="#">메뉴3</a>
            <ul class="submenu">
                <li><a href="#">서브메뉴3-1</a></li>
                <li><a href="#">서브메뉴3-2</a></li>
                <li><a href="#">서브메뉴3-3</a></li>
                <li><a href="#">서브메뉴3-4</a></li>
            </ul>
        </li>
        <li>
            <a href="#">메뉴4</a>
            <ul class="submenu">
                <li><a href="#">서브메뉴4-1</a></li>
                <li><a href="#">서브메뉴4-2</a></li>
                <li><a href="#">서브메뉴4-3</a></li>
                <li><a href="#">서브메뉴4-4</a></li>
            </ul>
        </li>
    </ul>
</nav>
/* nav */
.nav > ul {
    display: flex;
    justify-content: right;
    margin-top: 30px;
}
.nav > ul > li {
    position: relative;
}
.nav > ul > li > a {
    display: inline-block;
    padding: 10px 50px;
    background-color: #b0b0b0;
}
.nav > ul > li > a:hover {
    background-color: #696969;
}
.nav > ul > li > ul {
    position: absolute;
    left: 0; 
    top: 38px;
    width: 100%;
    text-align: center;
    display: none;
}
.nav > ul > li > ul > li > a {
    display: inline-block;
    padding: 10px;
    background-color: #c1c1c1;
    width: 100%;
    box-sizing: border-box;
}
.nav > ul > li > ul > li > a:hover {
    background-color: #8f8f8f;
}
/* 자바스크립트 CSS */
.nav > ul > li > ul {
    display: block;
    height: 0;
    overflow: hidden;
    transition: all 600ms;
}

2. 스크립트 작업 : 제이쿼리

제이쿼리를 작업하기 전에는 반드시 제이쿼리 라이브러리 파일을 연동하겠습니다. 버전은 상관없고 시험장에서 주는 파일을 연동하면 됩니다. 저는 절대주소로 작성하였지만, 여러분들은 상대주소로 적어주시면 됩니다.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

메뉴 유형1과 마찬가지로 li 선택자 $(".nav > ul > li")를 설정합니다. 마우스 오버효과 mouseenter를 설정하고, 자식 선택자 $(".nav > ul > li > ul")를 선택한 다음 천천히 보여주는 slideDown을 설정하면 됩니다. 메뉴 유형1에서는 $(this)를 사용했습니다. this를 사용하면 내가 오버한 부분에 대해서만 보여주지만 지금처럼 this를 쓰지 않고 $(".nav > ul > li > ul")를 선택하면, 서브 메뉴를 모두 보여주게 됩니다. 이것이 메뉴 유형1과 메뉴 유형2의 차이점입니다. 마우스 아웃도 마찬가지로 설정하면 되고, 여기서 stop()를 설정하는 이유는 마우스 오버를 연속적으로 빠르게 하게 되면, 마우스 오버를 하지 않아도 애니메이션이 계속 작동되게 됩니다. 애니메이션 명령어들이 연속적으로 작업이되면서, 끝나기도 전에 새로운 명령이 들어오기 때문에 순차적으로 처리하기 때문에 그런 현상이 생깁니다. 그런 현상을 막아주기 위해서 stop() 메서드를 사용하여 필요없는 명령어는 그때 그때 제거해주어서 버그 같은 현상을 제거해주게 됩니다. 이렇게 하면 메뉴 유형2도 완성이 되었습니다. 여기서 마무리 하셔도 되구요! 자바스크립트를 도전하셔도 됩니다.

$(function(){
    $(".nav > ul > li").mouseover(function(){        
        $(".nav > ul > li > ul").stop().slideDown(200);    
    });

    $(".nav > ul > li").mouseout(function(){
        $(".nav > ul > li > ul").stop().slideUp(200);
    });
})

3. 스크립트 작업 : 자바스크립트

navList 변수를 만들고 ul까지만 설정합니다. ul에 마우스 오버 했을 때 ul의 자식들 .submenu를 선택하고 높이값을 152px을 설정합니다. submenu가 여러개 있기 때문에 forEach를 설정해서 다 같이 움직이도록 설정했습니다. 자바스크립트는 애니메이션이 작동하지 않기 때문에 transition 설정을 CSS에 별개로 작업해주어야 합니다. heigth 값이 0일 때에는 넘치는 부분이 보이지 않도록 overflow: hidden;을 작업해주어야 합니다. 마우스 아웃 했을 때에도 똑같은 방법으로 처리해주고 height 값은 0으로 처리해주면 자연스럽게 애니메이션이 구현됩니다. 제이쿼리보다 신경써야 할 부분이 많지만 원리는 비슷하기 때문에 알아두면 좋을 것 같습니다.

window.onload = function(){
    let navList = document.querySelector(".nav > ul");

    navList.addEventListener("mouseover", function(){
        navList.querySelectorAll(".submenu").forEach(sub => {
            sub.style.height = "155px";
        });
    });
    navList.addEventListener("mouseout", function(){
        navList.querySelectorAll(".submenu").forEach(sub => {
            sub.style.height = "0px";
        });
    });
}
/* 자바스크립트 CSS */
.nav > ul > li > ul {
    display: block;
    height: 0;
    overflow: hidden;
    transition: all 600ms;
}

3. 마무리

두번째 메뉴 유형도 완성이 되었습니다. 스크립트를 처음 해보는 분들은 제이쿼리가 더 쉽기 때문에 제이쿼리로 하는 것을 추천하고, 조금 자신있다 싶으면 자바스크립트 작업하는 것을 추천합니다. 자바스크립트와 제이쿼리의 가장 큰 차이점은 다중 선택입니다. 자바스크립트는 다중 선택을 할 경우 그 부분을 반복적으로 처리해주는 forEach를 설정해줘야 합니다. 이 부분이 조금 어려울 수 있지만, 이 부분은 다음 튜토리얼에서 좀 더 자세히 다루어 보겠습니다. 수고하셨습니다. 🥳


PDF 샘플

레이아웃

스크립트 유형

실전 사이트 유형

댓글