Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 바닐라 자바스크립트
- 팝업레이어
- 웹개발키워드
- sqld52회차
- 바닐라자바스크립트
- IP차단
- JS
- SQLD후기
- 로또 회차
- 애니메이션
- TweenMax.js
- VANILLA
- git
- Python
- 텍스트조절
- SQL
- Slide
- 웹표준
- 기초
- jQuery
- 프론트앤드키워드
- sqld
- 웹접근성
- 코딩공부
- github
- CSS
- JSP
- 마우스커서
- asp
- 바닐라스크립트
Archives
- Today
- Total
단비의 코딩 공부 blog
[Vanilla JS]study 16일차 - 웹 컨텐츠 제작 - 메인 메뉴 본문
1. 전체메뉴
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JS - 메인 네비게이션</title>
<link type="text/css" rel="stylesheet" href="common01.css" />
</head>
<body>
<header>
<nav class="tnav">
<ul>
<li><a href="#">탑메뉴1</a></li>
<li><a href="#">탑메뉴2</a></li>
<li><a href="#">탑메뉴3</a></li>
<li><a href="#">탑메뉴4</a></li>
</ul>
</nav>
<h1>로고</h1>
<!-- 메인네비게이션 전체묶음 -->
<nav id="gnb">
<ul>
<li>
<!-- 메인메뉴 -->
<a href="#" class="mainnav">메인메뉴1</a>
<!-- 서브메뉴 -->
<ul class="subnav">
<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>
<li><a href="#">하위메뉴1_5</a></li>
<li><a href="#">하위메뉴1_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴2</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴2_5</a></li>
<li><a href="#">하위메뉴2_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴3</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴3_5</a></li>
<li><a href="#">하위메뉴3_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴4</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴4_5</a></li>
<li><a href="#">하위메뉴4_6</a></li>
</ul>
</li>
<li>
<a href="#" class="mainnav">메인메뉴5</a>
<ul class="subnav">
<li><a href="#">하위메뉴5_1</a></li>
<li><a href="#">하위메뉴5_2</a></li>
<li><a href="#">하위메뉴5_3</a></li>
<li><a href="#">하위메뉴5_4</a></li>
<li><a href="#">하위메뉴5_5</a></li>
<li><a href="#">하위메뉴5_6</a></li>
</ul>
</li>
</ul>
<!-- 서브메뉴 배경 : 동적생성할 예정-->
<div id="subbg"></div>
</nav>
</header>
<section></section>
<footer></footer>
<script src="common01.js"></script>
</body>
</html>
/* base */
*{ padding: 0; margin: 0; font-size: 12px; color: #666666; }
li{ list-style: none; }
a{ text-decoration: none; }
/* layout */
header{ width: 1000px; height: 100px; margin: 0 auto; background-color: bisque; }
section{ width: 1000px; height: 900px; margin: 0 auto; background-color: lightblue; }
footer{ width: 1000px; height: 100px; margin: 0 auto; background-color: pink; }
.tnav{ width: 1000px; height: 30px; background-color: orange; }
header h1{ float: left; width: 150px; height: 70px; background-color: lightcyan; }
#gnb{ float: left; width: 850px; height: 70px; }
/* tnav */
.tnav ul{ float: right; }
.tnav li{ float: left; margin: 0 5px; line-height: 30px; }
/* gnb */
#gnb > ul > li{
float: left; width: 20%; height: 70px; text-align: center; line-height: 69px;
position: relative; /* 자손인 subnav의 위치를 li기준에 맞추기 위해 */
}
#gnb .mainnav{
display: block; width: 100%; height: 100%;
font-size: 16px; color: #333; font-weight: bold;
}
#gnb li:hover .mainnav{ color: red; }
/* 메인메뉴 활성화 */
#gnb .mainnav.active{ color: red; }
/* subnav */
.subnav{
width: 100%; height: 0; overflow: hidden;
line-height: 40px;
position: absolute; /* 뒤에 보일 컨텐츠보다 화면 깊이상 앞에 보여야 함 */
z-index: 1001; /* subbg보다 z-index수치가 높아야함 */
top: 70px; left: 0;
transition: 0.3s ease-in-out;
}
.subnav a:hover{ text-decoration: underline; }
#subbg{
width: 100%; height: 0;
background-color: rgba(0,255,0,0.5);
position: absolute; top: 100px; left: 0;
z-index: 1000; /* 서브메뉴보다 깊이상 아래 존재 */
transition: 0.3s ease-in-out;
}
/* 활성화 처리 */
.subnav.active, #subbg.active{ height: 240px; }
//1. 문서객체 선택
const gnb = document.getElementById('gnb');
const mainnav = gnb.getElementsByClassName('mainnav');
const subnav = gnb.getElementsByClassName('subnav');
//2. subbg를 동적생성
const subbg = document.createElement('div');
subbg.setAttribute('id', 'subbg');
gnb.appendChild(subbg); //gnb의 마지막 자손으로 처리
//3. 이벤트로 받는 동일 명령이 많음 - 함수에 담기
activeFx = () => { //활성 함수
//subbg보이게 처리
subbg.classList.add('active');
for(let i=0;i<subnav.length;i++){
subnav[i].classList.add('active');
}
}
unactiveFx = () => { //비활성 함수
//subbg보이게 처리
subbg.classList.remove('active');
for(let i=0;i<subnav.length;i++){
subnav[i].classList.remove('active');
}
//메인메뉴 활성제거
mainnavdefalut();
}
//메인메뉴 활성을 모두 제거
mainnavdefalut = () => {
for(let j=0;j<mainnav.length;j++){
mainnav[j].classList.remove('active');
}
}
//4. 마우스 이벤트
//4-1. mouseenter
gnb.addEventListener('mouseenter', activeFx);
//4-1. mouseleave
gnb.addEventListener('mouseleave', unactiveFx);
//5. 웹접근성 - 키보드 접근성
//5-1. 첫번째 메인메뉴에 초점받았을 때
mainnav[0].addEventListener('focus', activeFx);
//5-2. 모든 메인메뉴에 초점을 받으면 해당 메인메뉴활성
for(let i=0;i<mainnav.length;i++){
mainnav[i].addEventListener('focus', function(){
mainnavdefalut(); //전부 제거 후
this.classList.add('active'); //이벤트 받은 대상만 active처리
});
}
//5-3. 마지막 하위리스트의 a태그에서 탭키를 눌렀을 때 모든 것이 비활성화
const lastNum = subnav.length - 1; //마지막 인덱스 번호를 담는 변수
const lastLink = subnav[lastNum].lastElementChild.firstElementChild;
lastLink.addEventListener('keydown', function(e){
if(e.keyCode == 9){ //tab키를 눌렀을 때
if(!e.shiftKey){ //쉬프트키는 누르지 않았다면
unactiveFx();
mainnavdefalut();
}
}
});
//5-4. 첫번째 메인메뉴에서 shift+tab키를 눌렀을 때 모두 비활성화
mainnav[0].addEventListener('keydown', function(e){
if(e.keyCode == 9){ //tab키를 눌렀을 때
if(e.shiftKey){ //쉬프트키를 눌렀다면
unactiveFx();
mainnavdefalut();
}
}
});
//5-5. 각각 하위메뉴의 마지막 a태그에 초점을 받았을 해당 메인메뉴 활성
for(let i=0;i<subnav.length;i++){
const a = subnav[i].lastElementChild.firstElementChild;
a.addEventListener('focus', function(){
mainnavdefalut(); //모든 메인메뉴 active제거 후
this.parentNode.parentNode.previousElementSibling.classList.add('avtive');
});
}
2. 각각메뉴
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>JS - 메인 네비게이션</title>
<link type="text/css" rel="stylesheet" href="common02.css" />
</head>
<body>
<header>
<nav class="tnav">
<ul>
<li><a href="#">탑메뉴1</a></li>
<li><a href="#">탑메뉴2</a></li>
<li><a href="#">탑메뉴3</a></li>
<li><a href="#">탑메뉴4</a></li>
</ul>
</nav>
<h1>로고</h1>
<!-- 메인메뉴 전체 묶음 -->
<nav id="gnb">
<ul>
<li>
<!-- 메인메뉴 -->
<a href="#" class="mainnav">메인메뉴1</a>
<!-- 서브메뉴 -->
<ul class="subnav">
<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>
<li><a href="#">하위메뉴1_5</a></li>
<li><a href="#">하위메뉴1_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴2</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴2_5</a></li>
<li><a href="#">하위메뉴2_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴3</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴3_5</a></li>
<li><a href="#">하위메뉴3_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴4</a>
<ul class="subnav">
<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>
<li><a href="#">하위메뉴4_5</a></li>
<li><a href="#">하위메뉴4_6</a></li>
</ul>
</li>
<li><a href="#" class="mainnav">메인메뉴5</a>
<ul class="subnav">
<li><a href="#">하위메뉴5_1</a></li>
<li><a href="#">하위메뉴5_2</a></li>
<li><a href="#">하위메뉴5_3</a></li>
<li><a href="#">하위메뉴5_4</a></li>
<li><a href="#">하위메뉴5_5</a></li>
<li><a href="#">하위메뉴5_6</a></li>
</ul>
</li>
</ul>
</nav>
</header>
<section></section>
<footer></footer>
<script src="common02.js"></script>
</body>
</html>
/* base */
*{ padding: 0; margin: 0; font-size: 12px; color: #666666; }
li{ list-style: none; }
a{ text-decoration: none; }
/* layout */
header{ width: 1000px; height: 100px; margin: 0 auto; background-color: lightblue; }
section{ width: 1000px; height: 900px; margin: 0 auto; background-color: antiquewhite; }
footer{ width: 1000px; height: 100px; margin: 0 auto; background-color: lightcyan; }
.tnav{ width: 1000px; height: 30px; background-color: orange; }
header h1{ float: left; width: 150px; height: 70px; background-color: bisque; }
#gnb{ float: left; width: 850px; height: 70px; }
/* tnav */
.tnav ul{ float: right; }
.tnav li{ float: left; margin: 0 5px; line-height: 30px; }
/* gnb */
#gnb > ul > li{ float: left; width: 20%; height: 70px; text-align: center; line-height: 70px; position: relative; } /* 하위메뉴 위치 컨트롤 */
#gnb > ul > li > a{ display: block; width: 100%; height: 100%; font-size: 16px; font-weight: bold; color: #333333; }
#gnb > ul > li:hover > a{ color: #FF0000; }
/* 제이쿼리에서 하위메뉴에 오버시 메인메뉴에도 색상이 변경되게 처리 */
#gnb > ul > li > a.active{ color: #FF0000; }
.subnav{
position: absolute; top: 60px; left: 0; width: 170px; height: 0; overflow: hidden; line-height: 40px; box-sizing: border-box; background-color: #FFFFFF;
z-index: 1000; /* 메인이미지 슬라이더보다 위에 올라오게 처리하기 위해 z-index 사용 */
transition: 0.3s ease-in-out;
}
/* 활성화 */
.subnav.active{ height: 240px; }
//1.문서객체 선택
const mainnav = document.querySelectorAll('#gnb .mainnav');
const subnav = document.querySelectorAll('#gnb .subnav');
//2. 마우스이벤트 - 메인메뉴에 마우스를 올렸을 때 활성
for(let i=0; i<mainnav.length;i++){
mainnav[i].addEventListener('mouseenter', function(){
//this : 메인메뉴
this.nextElementSibling.classList.add('active');
//부모인 li태그에서 마우스가 벗어났을 때 비활성
this.parentNode.addEventListener('mouseleave', function(){
//this : 부모인 li태그
this.firstElementChild.classList.remove('active');
this.lastElementChild.classList.remove('active');
});
});
//3. 웹접근성
//3-1. 각각의 메인메뉴에 초점받으면 활성화
mainnav[i].addEventListener('focus', function(){
//모든 건 비활성 후
//모든 하위메뉴의 a태그에 초점 비활성
for(let j=0;j<mainnav.length;j++){
mainnav[j].classList.remove('active');
subnav[j].classList.remove('active');
const a = subnav[j].getElementsByTagName('a');
for(let k=0;k<a.length;k++){
a[k].setAttribute('tabindex','-1'); //초점받지 못하게 처리
}
}
//초점받은 대상만 활성
this.classList.add('active');
this.nextElementSibling.classList.add('active');
//초점받은 메인메뉴의 하위메뉴 a만 초점 활성
const activeLink = this.nextElementSibling.getElementsByTagName('a')
for(let j=0;j<activeLink.length;j++){
activeLink[j].setAttribute('tabindex', 0); //초점 활성
}
});
}
//3-2. 첫번째 메인메뉴에서 shift+tab누르면 비활성 처리
mainnav[0].addEventListener('keydown', function(e){
if(e.keyCode == 9){
if(e.shiftKey){
this.classList.remove('active');
this.nextElementSibling.classList.remove('active');
}
}
});
//3-3. 마지막 하위메뉴 a태그에서 tab키를 눌렀을 때 비활성
const lastNum = subnav.length -1;
const subnavLast = subnav[lastNum].lastElementChild.firstElementChild;
subnavLast.addEventListener('keydown', function(e){
if(e.keyCode == 9){
if(!e.shiftKey){
mainnav[lastNum].classList.remove('active');
subnav[lastNum].classList.remove('active');
}
}
});
'javascript&jquery' 카테고리의 다른 글
[Vanilla JS]study 18일차 - 웹 컨텐츠 제작 - 갤러리 (0) | 2023.03.28 |
---|---|
[Vanilla JS]study 17일차 - 웹 컨텐츠 제작 - 탭바 (0) | 2023.03.27 |
[Vanilla JS]study 15일차 - 웹 컨텐츠 제작 - 검색 필터 (0) | 2023.03.23 |
[Vanilla JS]study 14일차 - 웹 컨텐츠 제작 - 보드프리뷰 (0) | 2023.03.22 |
[Vanilla JS]study 13일차 - 웹 컨텐츠 제작 - 드롭 다운 메뉴 (0) | 2023.03.21 |