Bootstrap 5를 활용한 멀티 레벨 드롭다운 리스트 구현
추천 자료: ASP.NET Core 인증 및 권한 부여
멀티 레벨 드롭다운 리스트는 웹사이트나 애플리케이션에서 복잡한 내비게이션 구조를 효율적으로 관리할 수 있게 해줍니다. Bootstrap 5와 함께 사용하면, 이러한 멀티 레벨 드롭다운 메뉴를 손쉽게 구현할 수 있습니다. 다음은 Bootstrap 5를 활용하여 멀티 레벨 드롭다운 리스트를 구현하는 방법을 단계별로 설명합니다.
CSS 스타일링
멀티 레벨 드롭다운 리스트의 기본적인 구조와 스타일을 정의합니다.
<style>
.dropdown-submenu {
position: relative; /* 상대적 위치 설정으로, 절대 위치를 가진 자식 요소들의 기준점을 설정합니다. */
}
.dropdown-submenu a::after {
transform: rotate(-90deg); /* 가상 요소(대개 화살표)를 -90도 회전시킵니다. */
position: absolute; /* 가상 요소를 상대적 위치를 가진 부모 요소 내에서 절대 위치로 설정합니다. */
right: 6px; /* 부모 요소의 오른쪽 가장자리에서 6px 떨어진 곳에 위치시킵니다. */
top: .8em; /* 부모 요소의 상단에서 .8em 떨어진 곳에 위치시킵니다. */
}
.dropdown-submenu .dropdown-menu {
top: 0; /* 서브메뉴의 상단을 부모 메뉴의 상단과 맞춥니다. */
left: 100%; /* 서브메뉴를 부모 메뉴의 바로 오른쪽에 위치시킵니다. */
margin-left: .1rem; /* 부모 메뉴와의 간격을 위해 왼쪽 여백을 조금 추가합니다. */
margin-right: .1rem; /* 일관된 간격을 위해 오른쪽 여백을 조금 추가합니다. */
}
</style>
HTML 구조
HTML에서는 Bootstrap 클래스를 사용하여 드롭다운 메뉴를 구성합니다. 다음 예시는 멀티 레벨 드롭다운 메뉴를 구성하는 방법을 보여줍니다.
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<!-- Navbar Brand -->
<a class="navbar-brand" href="#">Your Brand</a>
<!-- Toggler/Collapsibe Button -->
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navbar links -->
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<!-- Single level Dropdown -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" href="#" id="navbarBooks" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Books
</a>
<ul class="dropdown-menu" aria-labelledby="navbarBooks">
<li><a class="dropdown-item text-dark" href="#">C# 교과서</a></li>
<li><a class="dropdown-item text-dark" href="#">ASP.NET & Core를 다루는 기술</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item text-dark" href="#">Something else here</a></li>
</ul>
</li>
<!-- Multi-level Dropdown -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" href="#" id="navbarCourses" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Courses
</a>
<ul class="dropdown-menu" aria-labelledby="navbarCourses">
<!-- First level Dropdown -->
<li class="dropdown-submenu">
<a class="dropdown-item dropdown-toggle text-dark" href="#">DevLec</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">C#</a></li>
<li><a class="dropdown-item" href="#">ASP.NET Core</a></li>
</ul>
</li>
<!-- Nested level Dropdown -->
<li class="dropdown-submenu">
<a class="dropdown-item dropdown-toggle text-dark" href="#">VisualAcademy</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Youtube</a></li>
<li class="dropdown-submenu">
<a class="dropdown-item dropdown-toggle text-dark" href="#">JavaCampus</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Java</a></li>
<li><a class="dropdown-item" href="#">Spring Boot</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- Additional elements like login or others can be added here -->
</div>
</div>
</nav>
</header>
JavaScript 인터랙션
드롭다운 메뉴의 동작을 제어하기 위해 JavaScript를 사용합니다. 다음 스크립트는 드롭다운 요소의 클릭 이벤트를 처리하고, 서브 메뉴의 표시 상태를 토글합니다.
<script>
// 문서가 완전히 로드되었을 때 스크립트가 실행되도록 합니다.
document.addEventListener('DOMContentLoaded', function () {
// 모든 드롭다운 토글 요소를 선택합니다.
var dropdownToggleElements = document.querySelectorAll('.dropdown-submenu .dropdown-toggle');
// 각 토글 요소에 대한 이벤트 리스너를 설정합니다.
dropdownToggleElements.forEach(function (dropdownToggle) {
dropdownToggle.addEventListener('click', function (event) {
event.preventDefault(); // 클릭에 의한 기본 동작을 방지합니다.
event.stopPropagation(); // 이벤트가 상위로 전파되는 것을 방지합니다.
// 클릭된 토글 바로 다음에 오는 서브 메뉴를 선택합니다.
var currentSubMenu = this.nextElementSibling;
// 현재 서브 메뉴가 보이는 상태인지 확인합니다.
var isCurrentlyShown = currentSubMenu.classList.contains('show');
// 현재 토글의 상위 메뉴를 찾습니다.
var parentMenu = this.parentElement.parentElement.closest('.dropdown-submenu');
// 만약 상위 메뉴가 있고 현재 서브 메뉴가 열려 있다면, 서브 메뉴를 닫습니다.
if (parentMenu && isCurrentlyShown) {
closeSubMenu(currentSubMenu);
return; // 추가 실행을 중단합니다.
}
// 상위 메뉴를 클릭했을 때, 다른 모든 서브 메뉴를 닫고 현재 메뉴의 상태를 토글합니다.
if (!parentMenu) {
closeAllSubMenus(this); // 다른 모든 서브 메뉴를 닫습니다.
if (!isCurrentlyShown) {
currentSubMenu.classList.add('show'); // 현재 메뉴를 엽니다.
}
} else {
// 하위 메뉴를 클릭했을 때 현재 메뉴의 상태에 따라 토글합니다.
if (!isCurrentlyShown) {
currentSubMenu.classList.add('show'); // 현재 메뉴를 엽니다.
} else {
closeSubMenu(currentSubMenu); // 현재 메뉴를 닫습니다.
}
}
});
});
// 지정된 요소를 제외한 모든 서브 메뉴를 닫는 함수입니다.
function closeAllSubMenus(exceptThis) {
document.querySelectorAll('.dropdown-submenu .dropdown-menu').forEach(function (menu) {
if (!exceptThis.contains(menu)) {
closeSubMenu(menu); // 서브 메뉴를 닫습니다.
}
});
}
// 지정된 메뉴와 그 하위 메뉴를 닫는 함수입니다.
function closeSubMenu(menu) {
menu.classList.remove('show'); // 메뉴를 닫습니다.
var subMenus = menu.querySelectorAll('.dropdown-menu');
subMenus.forEach(function (subMenu) {
subMenu.classList.remove('show'); // 하위 메뉴를 닫습니다.
});
}
});
</script>
전체 소스 코드는 VisualAcademy 프로젝트를 참고하세요.
추천 자료: .NET Blazor에 대해 알아보시겠어요? .NET Blazor 알아보기를 확인해보세요!