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
- VANILLA
- 웹표준
- 기초
- 팝업레이어
- JSP
- 코딩공부
- SQL
- 웹개발키워드
- sqld52회차
- 로또 회차
- 바닐라스크립트
- Slide
- jQuery
- 텍스트조절
- 바닐라자바스크립트
- 프론트앤드키워드
- Python
- TweenMax.js
- 애니메이션
- sqld
- JS
- CSS
- asp
- git
- 바닐라 자바스크립트
- 웹접근성
- IP차단
- 마우스커서
- github
- SQLD후기
Archives
- Today
- Total
단비의 코딩 공부 blog
[Vanilla JS]study 13일차 - 웹 컨텐츠 제작 - 드롭 다운 메뉴 본문
1. 아래로 떨어지는 유형
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>패밀리사이트 - 아래로 떨어지는 유형</title>
<link rel="stylesheet" href="fs01.css" />
</head>
<body>
<header></header>
<section></section>
<footer>
<!-- 패밀리사이트 전체묶음 -->
<div class="fSite">
<!-- 초점을 받기 위해 버튼 태그 -->
<button id="fsBtn">
FAMILYSITE
<span class="icon"><img src="down_icon.png" alt="다운아이콘"></span>
</button>
<!-- 클릭시 보여질 리스트 -->
<ul>
<!-- _blank : 새창으로 주소를 열기 -->
</ul>
</div>
</footer>
<script src="fs01.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: coral; }
section{ width: 1000px; height: 700px; margin: 0 auto; background-color: antiquewhite; }
footer{ width: 1000px; height: 200px; margin: 0 auto; background-color: lightblue; position: relative; } /* fSite의 위치 컨트롤 위해서 사용 */
/* fSite */
.fSite{ width: 150px; height: 130px; position: absolute; top: 10px; right: 10px; }
.fSite button{ width: 150px; height: 30px; border: 1px solid #CCCCCC; border-bottom: none; box-sizing: border-box; color: #FFFFFF; background-color: #333333; text-align: left; padding-left: 10px; line-height: 29px; cursor: pointer; }
.fSite button .icon{ float: right; display: block; width: 30px; height: 100%; border-left: 1px solid #CCCCCC; box-sizing: border-box; padding: 5px 0; text-align: center; }
/* 하위 리스트 */
.fSite ul{
position: absolute; top: 30px; left: 0;
width: 150px; padding: 0 10px;
border: 1px solid #ccc;
height: 0; /* 안보이게 처리 */
overflow: hidden;
box-sizing: border-box; background-color: #333333;
transition: 0.3s ease-out; /* 변화에 시간차처리 */
}
.fSite li{ margin-bottom: 5px; }
.fSite li a{ color: #FFFFFF; }/* 글자관련은 최종적으로 a가 지정 */
/* 버튼 활성화 처리 : 자바스크립트에서 클래스 컨트롤 */
.fSite button.active .icon{ transform: rotate(180deg); border-left: none; border-right: 1px solid #CCCCCC; } /* 아이콘 180도 회전 */
.fSite button.active + ul{ height: 100px; padding: 10px; } /* 높이를 처리 */
//버튼을 클릭하면 버튼 자신에게 active클래스 추가 혹은 제거하시오.
//1. 문서객체 선택
const fsBtn = document.getElementById('fsBtn');
//2. 클릭이벤트
fsBtn.addEventListener('click', function(){
this.classList.toggle('active');
});
//웹접근성 - 키보드 접근성
//tab키는 : 초점의 정방향
//shift + tab키 : 초점의 역방향
//초점을 받는 태그 : a, button, select, input, testarea
//3. 리스트의 마지막 a태그에서 키보드를 눌렀을 때, tab키일 때 active클래스를 제거
const lastLink = fsBtn.nextElementSibling.lastElementChild.firstElementChild;
//4. 키보드 이벤트 - shift키 눌렸는지 확인해야 해서 keydown이벤트 처리
lastLink.addEventListener('keydown', function(e){
//e : 이벤트 객체 - 눌린 키의 정보를 담는 객체
//탭키의 키코드 : 9
//shiftkey : 쉬프트키가 눌렸다면 true를 반환, 그렇지 않으면 false를 반환
if(e.keyCode == 9){ //tab키를 눌렀을 때
if(!e.shiftKey){
fsBtn.classList.remove('active'); // 버튼의 active 클래스 제거
}
}
});
2. 패밀리 사이트
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<title>패밀리사이트</title>
<link rel="stylesheet" href="fs02.css" />
</head>
<body>
<header></header>
<section></section>
<footer>
<div class="fSite">
<button id="fsBtn">
FAMILYSITE
<span class="icon"><img src="down_icon.png" alt="다운아이콘"></span>
</button>
<ul>
<!-- tabindex : 요소의 탭순서를 지정 -->
<!-- -1 : 초점받던 태그가 탭을 받지 못함 -->
<!-- 0 : 초점받지 못한 태그가 초점을 받고, 탭순서는 순서대로 자연스럽게 처리 -->
<!-- 초기상태에서 안보이지만 탭키 누르면 초점이 가기 위해 무너지기 때문에 초점을 못가게 막음 -->
</ul>
</div>
</footer>
<script src="fs02.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: coral; }
section{ width: 1000px; height: 700px; margin: 0 auto; background-color: antiquewhite; }
footer{ width: 1000px; height: 100px; margin: 0 auto; background-color: lightblue; position: relative; } /* fSite의 위치 컨트롤 위해서 사용 */
/* fSite */
.fSite{
width: 150px; height: 130px; position: absolute; top: -90px; right: 10px;
overflow: hidden; /* 현재 요소 영역에서 넘어간 자손을 안보이게 처리 */
}
.fSite button{ width: 150px; height: 30px; border: 1px solid #CCCCCC; box-sizing: border-box; color: #FFFFFF; background-color: #333333; text-align: left; padding-left: 10px; line-height: 29px; cursor: pointer; position: absolute; top: 100px; z-index: 10; } /* 버튼이 위쪽에 보여야 함 */
.fSite button .icon{ float: right; display: block; width: 30px; height: 100%; border-right: 1px solid #CCCCCC; box-sizing: border-box; padding: 5px 0; text-align: center; transform: rotate(180deg); }
.fSite ul{
padding: 10px; width: 150px; height: 100px; box-sizing: border-box; border: 1px solid #CCCCCC; background-color: #333333; border-bottom: none;
position: absolute; /* 형요소인 버튼보다 위쪽에 위치해야해서 변경 */
top: 100px; /* 처음 위치는 내려가 있어야 함 */
z-index: 9; /* 리스트가 아래 쪽에 보여야 함 */
transition: 0.3s ease-in-out; /* css의 변화에 시간차 처리 */
}
.fSite li{ margin-bottom: 5px; }
.fSite li a{ color: #FFFFFF; }/* 글자관련은 최종적으로 a가 지정 */
/* 활성버튼 */
.fSite button.active .icon{ transform: rotate(0deg); border-right: none; border-left: 1px solid #CCCCCC; }
.fSite button.active + ul{ top: 0; }
//버튼을 클릭하면 버튼 자신에게 active클래스 추가 혹은 제거하시오.
//1. 문서객체 선택
const fsBtn = document.getElementById('fsBtn');
//2. 클릭이벤트
fsBtn.addEventListener('click', function(){
this.classList.toggle('active');
//active클래스를 받았다면, a 태그가 초점을 받고, 그렇지않다면 초점을 받지 않게 처리
//setAttribute('속성명',값) : 문서객체의 태그 속성을 변경
//contains('클래스명') : 해당 클래스를 갖고 있으면 true반환, 그렇지 않으면false를 반환
//a태그를 문서객체로 선택 - 복수로 전부 선택
const activeLink = this.nextElementSibling.getElementsByTagName('a');
//클래스 유무여부
const has = this.classList.contains('active');
if(has){ //active클래스를 갖고 있다면
for(let i=0;i<activeLink.length;i++){
activeLink[i].setAttribute('tabindex','0'); //문자열로 담아줘야함 - 전부 초점처리
}
}else{ //active클래스를 갖고 있지 않다면
for(let i=0;i<activeLink.length;i++){
activeLink[i].setAttribute('tabindex','-1'); //문자열로 담아줘야함 - 전부 초점받지 못하게 처리
}
}
});
//3. 키보드 이벤트 (웹접근성)
const lastLink = fsBtn.nextElementSibling.lastElementChild.firstElementChild;
lastLink.addEventListener('keydown', function(e){
if(e.keyCode == 9){ // tab키를 눌렀을 때
if(!e.shiftKey){ // 시프트키를 누르지 않았다며
fsBtn.classList.remove('active'); // 버튼의 active 클래스 제거
//모든 a태그를 다시 선택
const activeLink = this.parentNode.parentNode.getElementsByTagName('a');
for(let i=0;i<activeLink.length;i++){
activeLink[i].setAttribute('tabindex','-1'); //문자열로 담아줘야함 - 전부 초점받지 못하게 처리
}
}
}
});
'javascript&jquery' 카테고리의 다른 글
[Vanilla JS]study 15일차 - 웹 컨텐츠 제작 - 검색 필터 (0) | 2023.03.23 |
---|---|
[Vanilla JS]study 14일차 - 웹 컨텐츠 제작 - 보드프리뷰 (0) | 2023.03.22 |
[Vanilla JS]study 12일차 - ES6 2 (0) | 2023.03.16 |
[Vanilla JS]study 11일차 - ES6 (0) | 2023.03.13 |
[Vanilla JS]study 10일차 - DOM2 (0) | 2023.03.10 |