티스토리 뷰

탭 키(Tab) 이동 순서를 [1차 메뉴 ①] → [1차 메뉴 ①의 하위 2/3차 메뉴] → [1차 메뉴 ②] 순서로 자연스럽게 흐르도록 수정했습니다.
이를 위해 기존의 '클릭 시 콘텐츠 전환' 방식이 아니라, HTML 구조상 1차 메뉴 바로 다음에 해당 2차 메뉴가 위치하도록 배치하는 것이 핵심입니다.
접근 방식
- 구조 변경: 1차 메뉴와 2차 메뉴를 물리적으로 인접하게 배치하여 탭 순서를 맞춥니다.
- CSS 레이아웃: flex 또는 absolute를 활용해 시각적으로는 여전히 왼쪽(1차)과 오른쪽(2차)이 나뉘어 보이도록 유지합니다.
- 스크립트: 1차 메뉴에 포커스가 가거나 클릭되었을 때 오른쪽 영역을 보여주도록 처리합니다.
완성된 HTML 코드
HTML
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>탭 순서 최적화 모바일 메뉴</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
ul { list-style: none; }
button { cursor: pointer; border: none; background: none; font-family: inherit; text-align: left; }
a { text-decoration: none; color: inherit; display: block; }
/* 메뉴 열기 버튼 */
.open-menu { padding: 15px; background: #333; color: #fff; margin: 20px; }
/* 레이어 팝업 */
.menu-layer {
display: none; position: fixed; top: 0; left: 0;
width: 100%; height: 100%; background: #fff; z-index: 1000;
}
.menu-header {
display: flex; justify-content: space-between; align-items: center;
padding: 0 15px; height: 60px; border-bottom: 1px solid #eee;
}
/* 메인 컨테이너 */
.menu-container { display: flex; height: calc(100% - 60px); position: relative; }
/* 왼쪽 1차 메뉴 영역 */
.nav-side { width: 35%; background: #f8f9fa; border-right: 1px solid #e9ecef; overflow-y: auto; }
/* 1차 메뉴 버튼 */
.d1-btn { width: 100%; padding: 20px 15px; font-size: 15px; border-bottom: 1px solid #eee; color: #666; }
.d1-btn.active { background: #fff; color: #007bff; font-weight: bold; }
/* 오른쪽 2차 메뉴 영역 (공통 컨테이너 역할만 함) */
.nav-content { width: 65%; background: #fff; overflow-y: auto; }
/* 실제 2차 메뉴 박스 (1차 메뉴 바로 다음에 위치하지만 시각적으로는 오른쪽에 배치) */
.depth2-wrapper {
display: none;
position: absolute; top: 0; right: 0; width: 65%; height: 100%;
background: #fff; padding: 10px 0; overflow-y: auto;
}
.depth2-wrapper.active { display: block; }
/* 2차/3차 메뉴 스타일 */
.d2-btn { width: 100%; padding: 15px 20px; font-size: 16px; border-bottom: 1px solid #f8f9fa; font-weight: 500; }
.d2-btn.has-sub::after { content: ' ▼'; font-size: 10px; color: #ccc; }
.depth3 { display: none; background: #fafafa; }
.depth3 a { padding: 12px 30px; font-size: 14px; color: #777; border-bottom: 1px solid #f1f1f1; }
</style>
</head>
<body>
<button class="open-menu">전체 메뉴 열기</button>
<div class="menu-layer">
<div class="menu-header">
<h2>전체메뉴</h2>
<button class="close-menu">닫기(✕)</button>
</div>
<div class="menu-container">
<nav class="nav-side">
<ul>
<li>
<button class="d1-btn active">패션/잡화</button>
<div class="depth2-wrapper active">
<div class="depth2-item">
<button class="d2-btn has-sub">여성의류</button>
<ul class="depth3">
<li><a href="#none">원피스</a></li>
<li><a href="#none">블라우스</a></li>
</ul>
</div>
<div class="depth2-item">
<a href="#none" class="d2-btn">남성의류 (바로가기)</a>
</div>
</div>
</li>
<li>
<button class="d1-btn">가전/디지털</button>
<div class="depth2-wrapper">
<div class="depth2-item">
<button class="d2-btn has-sub">주방가전</button>
<ul class="depth3">
<li><a href="#none">냉장고</a></li>
<li><a href="#none">전기밥솥</a></li>
</ul>
</div>
</div>
</li>
<li>
<button class="d1-btn">식품/리빙</button>
<div class="depth2-wrapper">
<div class="depth2-item">
<a href="#none" class="d2-btn">생활용품</a>
</div>
</div>
</li>
</ul>
</nav>
<div class="nav-content"></div>
</div>
</div>
<script>
$(document).ready(function() {
// 1. 레이어 열기/닫기
$('.open-menu').click(function() {
$('.menu-layer').show();
$('.close-menu').focus();
});
$('.close-menu').click(function() {
$('.menu-layer').hide();
$('.open-menu').focus();
});
// 2. 1차 메뉴 포커스 또는 클릭 시 해당 2차 메뉴 노출
// 'focusin'을 추가하여 탭 키로 이동 시에도 자동으로 오른쪽 메뉴가 바뀜
$('.d1-btn').on('click focusin', function() {
$('.d1-btn').removeClass('active');
$(this).addClass('active');
$('.depth2-wrapper').removeClass('active');
$(this).next('.depth2-wrapper').addClass('active');
});
// 3. 2차 메뉴 클릭 시 3차 메뉴 토글
$('.d2-btn.has-sub').click(function() {
$(this).next('.depth3').stop().slideToggle(300);
});
// 4. ESC 키 닫기
$(window).keydown(function(e) {
if (e.keyCode == 27) $('.close-menu').click();
});
});
</script>
</body>
</html>
💡 주요 변경 사항 및 특징
- 구조의 인접화 (탭 순서의 핵심):
- 기존에는 1차 메뉴 목록이 다 끝나야 2차 메뉴가 나왔습니다.
- 수정된 코드에서는 <li> 안에 1차 메뉴 버튼 바로 뒤에 2차 메뉴 박스를 배치했습니다.
- 따라서 탭 키를 누르면 [1차 메뉴 A] → [A의 하위 메뉴들] → [1차 메뉴 B] 순으로 논리적인 이동이 가능합니다.
- 포커스 이벤트(focusin) 활용:
- 마우스 클릭뿐만 아니라 키보드 탭으로 1차 메뉴에 접근했을 때도 우측의 2차 메뉴 내용이 자동으로 바뀌도록 스크립트를 구성했습니다. 사용자가 탭을 누를 때마다 눈으로 어떤 메뉴의 하위 항목을 보고 있는지 바로 알 수 있습니다.
- 시각적 레이아웃 유지:
- 구조는 수직적으로 배치되어 있지만, CSS에서 .depth2-wrapper에 position: absolute와 right: 0을 주어 사용자가 볼 때는 기존처럼 왼쪽과 오른쪽이 분리된 레이아웃으로 보이게 했습니다.
- 사용자 경험:
- 3차 메뉴가 있는 경우에만 2차 메뉴 클릭 시 열리도록 했으며, 탭 키로 3차 메뉴의 링크까지 모두 순차적으로 접근 가능합니다.
※ 해당 내용은 Google Gmini3.0에서 작성되었습니다.
'WEB > JQuery' 카테고리의 다른 글
| 폴더 트리메뉴 한글 검색포함 (1) | 2026.01.22 |
|---|---|
| 폴더 트리메뉴 (0) | 2026.01.22 |
| 배너 좌우 이동 jQuery (0) | 2025.01.10 |
| 모바일 메뉴 더보기 클릭 JQuery (0) | 2025.01.10 |
| jQuery 클릭히든뷰2 (1) | 2025.01.10 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 정보처리기사 #정보처리기사요약 #정보처리기사요점정리
- 테스크탑무선랜카드 #무선랜카드 #아이피타이무선랜카드 #a3000mini #무선랜카드추천
- 좋은책 #밥프록터 #부의원리
- jdk #jre
- thymeleaf
- 자바스크립트countiue
- 썬크림 #닥터지썬크림 #내돈내산 #내돈내산썬크림 #썬크림추천 #spf50썬크림 #닥터지메디유브이울트라선
- 자바스크립트 #javascript #math
- 광주분식 #광주분식맛집 #상추튀김 #상추튀김맛집 #광주상추튀김
- 무료폰트 #무료웹폰트 #한수원한돋움 #한수원한울림 #한울림체 #한돋움체
- 연명의료결정제도 #사전연명의료의향서 #사전연명의료의향서등록기관 #광주사전연명의료의향서
- echart
- 바지락칼국수 #월곡동칼국수 #칼국수맛집
- 파비콘 #파비콘 사이트에 적용
- 자바스크립트정규표현식
- sw기술자평균임금 #2025년 sw기술자 평균임금
- 자바스크립트break
- // 사진직: 데이터가 없으면 DEFAULT_IMG 사용 const profileSrc = (d.img && d.img !== "") ? d.img : DEFAULT_IMG;('#user-photo').attr('src'
- 와이파이증폭기추천 #와이파이설치
- iptime와이파이증폭기 #와이파이증폭기설치
- ajax
- 탭메뉴자바스크립트
- 좋은책
- SQL명령어 #SQL
- 증폭기 #아이피타임증폭기
- 파비콘사이즈
- lg그램pro #lg그램 #노트북 #노트북추천 #lg노트북
- 쇼팬하우어 #좋은책
- jQuery #jQuery이미지슬라이드 #이미지슬라이드
- css미디어쿼리 #미디어쿼리 #mediaquery
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함

