PINKYETI

[JavaScript] 반응형 웹 페이지 슬라이드 2단 메뉴바 만들기 (+HTML/CSS, 드롭다운 x) 본문

# Dev Note/[Frontend]

[JavaScript] 반응형 웹 페이지 슬라이드 2단 메뉴바 만들기 (+HTML/CSS, 드롭다운 x)

PINKYETI 2022. 4. 22. 04:03

 


안녕하세요. 핑크예티입니다.

최근 웹개발 프로젝트를 진행하며, Front-end 개발을 

맡게 되었는데요, 잘 모르는 영역이라 쉽지 않더라고요.

반응형 웹페이지 구현을 시작하다가 메뉴바

구현부터 막혀서 고생을 좀 했습니다.

 

최근 웹페이지에서 흔하게 볼 수 있는 형태의 2단 메뉴바 구성은

구글링을 통해서도 찾아보기 힘들더라고요.

그래서 제가 작성했던 방법을 공유하고자 펜을 들게 되었습니다.

 

성격 급하신 분들은, 전체 코드 & 메뉴바 예시부터 보고가세요.

 

- 메뉴바 예시

 

 

 

 

 

 

- 전체 코드

<!doctype html>
<html>
<head>
    <meta charset="utf-8">

    <!-- BootStrap / jQuery CDN 연동-->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>	
    <style>
        .sub-menu {
        display: none;
        position: absolute;
        background-color: black;
        width: 100%;        
        left: 0;
		top: 100%;
        z-index: 1;
        }
    </style>
</head>
<header class="p-3 bg-dark text-white" style="position: relative;">
    <div class="container">
        <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
            
            <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
                <li>
                    <a href="#" class="nav-link px-2 text-secondary">Home</a>
                </li>
                <li>
                    <a href="#" class="nav-link px-2 text-white">Menu 01</a>
                    <ul class="nav-item sub-menu">
                        <li class="nav-link" herf="#">Sub Menu 01</li>
                        <li class="nav-link" herf="#">Sub Menu 02</li>
                    </ul>
                </li>
                <li>
                    <a href="#" class="nav-link px-2 text-white">Menu 02</a>
                    <ul class="nav-item sub-menu">
                        <li class="nav-link" herf="#">Sub Menu 03</li>
                        <li class="nav-link" herf="#">Sub Menu 04</li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</header>
<script>
	<!-- mainMenuClick -->
		
        <!-- Main Menu 요소 가져오기 -->
	    let targetMainMenu = $("a.nav-link");
		
        <!-- Click Event Handler 선언 -->
        targetMainMenu.click(function() {
            <!-- 클릭된 Main Menu의 Sub Menu 요소 가져오기 -->
            var targetSubMenu = $(this).next("ul.nav-item");			

            for(var i=0; i < targetMainMenu.length; i++) {
                <!-- 클릭된 Main Menu 확인 조건문 -->
                if($(this).text() == targetMainMenu[i].innerText) {
                    <!-- Sub 메뉴 펼치기 / 닫기 -->
                    if(targetSubMenu.is(":visible")) {
                        targetSubMenu.slideUp();
                    } else {
                        targetSubMenu.slideDown();
                    }
                } else {
                    <!-- 펼쳐진 다른 Main Menu의 Sub Menu 감추기 -->
                    $(targetMainMenu[i]).next("ul.nav-item").css("display", "none");
                }
            }
        });

</script>
</html>

 

 

 

1. 반응형 웹 페이지 - 메뉴바 로직 설명

전체 소스 설명에 앞서, 메뉴바의 실행 로직에 대해 간단히 설명드릴게요.

간단히 메인 메뉴를 클릭하면 Sub 메뉴가 펼쳐지고

메인 메뉴를 한번 더 클릭하면 Sub 메뉴가 닫히는 메뉴바입니다.

이 때 고려될 사항은, Sub 메뉴가 펼쳐져 있을 때

다른 메인 메뉴를 클릭했을 시 사라지게 하는 로직이 추가되었습니다.

(Sub 메뉴가 펼쳐지는 방식은 주석 참고하셔서 튜닝하셔도 좋습니다.)

 

 

 

2. HTML/CSS/JavaScript 소스 설명

1) HTML <head>

<head>
    <meta charset="utf-8">

    <!-- BootStrap / jQuery CDN 연동-->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>	
    <style>
        .sub-menu {
        display: none;
        position: absolute;
        background-color: black;
        width: 100%;        
        left: 0;
        top: 100%;
        z-index: 1;
        }
    </style>
</head>

 - 메뉴바 템플릿은 BootStrap 예시를 참고하여 작성

 - BootStrap/jQuery HTML 연동은 cdn으로 연결

 - .sub-menu Class를 선언하여 Sub Menu Style 지정

    * display를 none으로 주어 브라우저 로딩 시 Sub Menu 안보이도록

    * position과 margin 설정으로 메뉴바 밑으로 Sub Menu 출력

    * z-index 를 통해 Sub Menu 출력 시 가장 앞에 보이도록

 

2) HTML <header>

<header class="p-3 bg-dark text-white" style="position: relative;">
    <div class="container">
        <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
            
            <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
                <li>
                    <a href="#" class="nav-link px-2 text-secondary">Home</a>
                </li>
                <li>
                    <a href="#" class="nav-link px-2 text-white">Menu 01</a>
                    <ul class="nav-item sub-menu">
                        <li class="nav-link" herf="#">Sub Menu 01</li>
                        <li class="nav-link" herf="#">Sub Menu 02</li>
                    </ul>
                </li>
                <li>
                    <a href="#" class="nav-link px-2 text-white">Menu 02</a>
                    <ul class="nav-item sub-menu">
                        <li class="nav-link" herf="#">Sub Menu 03</li>
                        <li class="nav-link" herf="#">Sub Menu 04</li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</header>

 - .sub-menu 제외 CSS Class는 BootStrap 템플릿이므로 무시

 - 부모 ul 아래 자식 ul을 넣어 2단 메뉴바 구성

 

3) HTML <script>

<script>
	<!-- mainMenuClick -->
		
        <!-- Main Menu 요소 가져오기 -->
        let targetMainMenu = $("a.nav-link");
		
        <!-- Click Event Handler 선언 -->
        targetMainMenu.click(function() {
            <!-- 클릭된 Main Menu의 Sub Menu 요소 가져오기 -->
            var targetSubMenu = $(this).next("ul.nav-item");			

            for(var i=0; i < targetMainMenu.length; i++) {
                <!-- 클릭된 Main Menu 확인 조건문 -->
                if($(this).text() == targetMainMenu[i].innerText) {
                    <!-- Sub 메뉴 펼치기 / 닫기 -->
                    if(targetSubMenu.is(":visible")) {
                        targetSubMenu.slideUp();
                    } else {
                        targetSubMenu.slideDown();
                    }
                } else {
                    <!-- 펼쳐진 다른 Main Menu의 Sub Menu 감추기 -->
                    $(targetMainMenu[i]).next("ul.nav-item").css("display", "none");
                }
            }
        });

</script>

<!-- Main Menu 요소 가져오기 -->

: a.nav-link 는 Main Menu의 요소들인데, jQuery 구문으로 변수에 모든 Main Menu의 요소를 배열로 선언

 

<!-- Click Event Handler 선언 -->

: 선언된 targetMainMenu 를 클릭했을 때, 함수 내의 로직을 실행시켜라

 

<!-- 클릭된 Main Menu의 Sub Menu 요소 가져오기 -->

: 클릭 이벤트가 일어난 Main Menu를 $(this) 로 구별. 클릭된 Main Menu의 Sub Menu(ul.nav-item) 을 변수로 지정

 

<!-- 클릭된 Main Menu 확인 조건문 -->

: 클릭 이벤트가 일어난 Main Menu를 전체 Main Menu 배열에서 구분하기 위한 조건문

 

<!-- Sub 메뉴 펼치기 / 닫기 -->

: 클릭 이벤트가 일어난 Main Menu가 visible 인지에 따라, 메뉴 펼치기 / 접기

 

<!-- 펼쳐진 다른 Main Menu의 Sub Menu 감추기 -->

: 클릭 이벤트가 일어난 Main Menu 외에, Sub Menu가 펼쳐져 있는 경우 모두 안보이게

 

 

실제 브라우저에서 확인된 모습을 마지막으로

펜을 놓도록 하겠습니다.

빈약하지만, Front-end 개발에 입문하신 분들께

많은 도움이 되었으면 좋겠습니다 :)