Home > 웹 콘텐츠 신기술 제작기법 > 접근성 있는 JavaScript 제작기법 > JavaScript 애플리케이션 콘텐츠 구현 예 >
내비게이션 제작기법

(1) 가로 탭 메뉴와 Enter키의 조합
아래의 예제는 Tab 키에 의하여 주 메뉴를 한차례 이동한 후에 순차적으로 화면에 나타난 하위 메뉴 및 ‘더보기’ 링크로 이동하는 ‘가로 탭’ 메뉴이다. Tab 키로 이동 중에 Enter 키를 누르면 해당 주 메뉴에 속한 하위 메뉴가 펼쳐지고, 하위 메뉴의 첫 번째 메뉴로 초점이 이동한다.

[그림] Enter키에 의해 동작하는 가로 탭 메뉴 예제
Shift + Tab 키에 의한 이동 순서는 다음과 같다. 초점이 주 메뉴에 있을 경우에는 주 메뉴를 역순으로 이동한다. 만일 초점이 하위 메뉴에 있으면 해당 하위 메뉴를 역순으로 이동한 후에 주 메뉴를 읽어주고, 이어서 주 메뉴 간을 역순으로 이동한다. 화면 낭독 프로그램이 설치되어도 Tab 키와 Shift + Tab 키에 의한 초점 이동이 정상적이어야 하며, 초점이 주어지는 요소의 텍스트 또는 대체 텍스트를 읽어주어야 한다.
//HTML Document
<head>
<title>가로 탭 메뉴 Type1</title>
<link rel="stylesheet" href="./common/style.css" type="text/css" />
<script type="text/javascript" src="./common/script.js"></script>
</head>
<body>
<div id="TabMenu">
<div id="TabMenuSub">
<ul><li><a href="#TabNotice0">
<img src="./img/menua_off.gif" alt="공지사항" /></a></li>
<li><a href="#TabNotice1">
<img src="./img/menub_off.gif" alt="입법예고" /></a></li>
<li><a href="#TabNotice2">
<img src="./img/menuc_off.gif" alt="보도자료" /></a></li>
<li><a href="#TabNotice3">
<img src="./img/menud_off.gif" alt="해명자료" /></a></li></ul></div>
<div id="TabNotice0" class="TabNoticeStyle">
<ul><li>
<a href="./notice.html" >광주지방 정부청사 금융기관 선정결과</a></li>
<li><a href="./notice.html" >행정안전부 겨울방학 대학생... </a></li>
<li><a href="./notice.html">2008년도 공무원연금운영위원회 회의록</a></li>
<li><a href="./notice.html">2007년도 제5회 공무원연금운영위원회...</a></li>
<li><a href="./notice.html">생활공감정책 국민아이디어 공모 ...</a></li>
</ul>
<a href="./noticemore.html" class="more" onblur="checkLink(0)">
<img src="./img/btn_more.gif" alt="공지사항 더보기" /></a></div>
..
</div>
<script type="text/javascript">
var TabMenu1 = new fnTabMenu_Type1;
TabMenu1.MenuName = "TabMenuSub";
TabMenu1.DivName = "TabNotice";
TabMenu1.fnName = "TabMenu1";
TabMenu1.Start();
</script>
</body>
// JavaScript Document
function fnTabMenu_Type1() {
this.CurrentMenu = 0;
this.Start = function() {
this.MenuBox=document.getElementById(this.MenuName)
.getElementsByTagName("ul")[0].getElementsByTagName("li");
// 탭 메뉴의 갯수를 파악하는 부분
this.MenuLength = this.MenuBox.length;
// 탭 메뉴의 링크부분에 마우스나 키보드의 반응을 넣는 부분
for(var i=0; i<this.MenuLength; i++ ){
this.MenuLink=this.MenuBox.item(i).getElementsByTagName("a")[0];
this.MenuLinkBtn= this.MenuLink.getElementsByTagName("img")[0];
if(i == this.CurrentMenu){
document.getElementById(this.DivName + i).style.display = "block";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_off.", "_on.");}
else{document.getElementById(this.DivName + i).style.display = "none";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_on.", "_off.");}
this.MenuLink.i = i;
this.MenuLink.fnName = this.fnName;
this.MenuLink.onclick = function() {
eval( this.fnName +".fnMouseOver(" + this.i + ")");
return false;}
// 주 메뉴에서 Enter 키를 눌렀을 경우
this.MenuLink.onkeydown=function(e){
if(event.keyCode == 13){
eval( this.fnName +".fnMouseOver2(" + this.i + ")");} }
// 주 메뉴의 가장 마지막 링크에서 포커스를 검사한다.
// 현재 주 메뉴가 선택되어 있고 링크가 하위 메뉴에 있다면,
// 이전에 선택한 주 메뉴로 포커스를 이동시킨다.
if(i == this.MenuLength-1){
this.MenuLink.onfocus = function(){
try{if(currentTab < i && isSubMenu){
document.getElementById("TabMenuSub")
.getElementsByTagName("a")[currentTab].focus();
isSubMenu = false;} }catch(e){
}
return false;
}
}
}
}
//탭 메뉴의 링크부분에 마우스나 키보드 반응에 의해 실행하는 부분
this.fnMouseOver = function(val) {
for ( var i=0; i<this.MenuLength; i++) {
this.MenuLink=this.MenuBox.item(i)
.getElementsByTagName("a")[0];
this.MenuLinkBtn=this.MenuLink.getElementsByTagName("img")[0];
if(i==val){
document.getElementById(this.DivName+i).style.display="block";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_off.", "_on.");}
else{document.getElementById(this.DivName+i).style.display="none";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_on.", "_off.");}
}
}
this.fnMouseOver2=function(val){
currentTab = val;
isSubMenu = true;
for(var i=0; i<this.MenuLength; i++){
this.MenuLink=this.MenuBox.item(i).getElementsByTagName("a")[0];this.MenuLinkBtn
=this.MenuLink.getElementsByTagName("img")[0];
if(i==val){document.getElementById(this.DivName+i).style.display="block";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_off.", "_on.");}
else{document.getElementById(this.DivName+i).style.display="none";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_on.", "_off.");}
// 하위 메뉴의 첫번째 링크로 초점이 이동
if(i == val){
document.getElementById("TabNotice"+ val).getElementsByTagName("a")[0].focus();}
}
}
}
// 더보기를 눌렀을 경우 주 메뉴에서
// 선택되지 않은 다음 메뉴가 있는지 검사한다.
function checkLink(id){
try{ var obj = document.getElementById("TabMenuSub")
.getElementsByTagName("a")[id + 1];
obj.focus();}catch(e){
}
}
(2) 가로 탭 메뉴와 롤오버 기능의 조합
아래 예제는 Tab 키를 이용하여 주 메뉴로 초점을 이동시키면, 하위 메뉴가 자동적으로 나타나는 롤오버 기능을 이용한 ‘가로 탭’ 메뉴이다. 이 문서의<II - 5.1.4(1) 가로 탭 메뉴와 Enter키의 조합>과의 차이점은, Tab 키로 이동할 때 해당 주 메뉴에 속한 하위 메뉴가 자동적으로 펼쳐지고, 이후에 Tab 키를 누르면 하위 메뉴의 첫 번째 메뉴로 초점이 이동한다는 점이다.
예를 들어 아래 그림에서 Tab 키에 의한 이동순서는 ‘공지사항’, ‘광주지방 ... 선정 결과 ’, ‘행정안전부 ... 당첨자발표’, ... ‘생활 공감정책 ... 안내’의 순서이다. 이어서 ‘더보기’ 링크로 이동하고, 다음 주 메뉴인 ‘입법예고’ 링크로 이동한다. 이어서 자동적으로 ‘입법예고’의 하위 메뉴가 펼쳐지고, 하위 메뉴를 하나씩 이동한 후, 마지막으로 ‘더보기’ 링크로 이동한다.
Shift + Tab 키에 의한 이동 순서는 Tab 키에 의한 이동순서의 역순과 차이가 있다. 만일 초점이 하위 메뉴에 있을 경우에는 하위 메뉴를 역순으로 읽어준 후에 주 메뉴를 읽어주고, 이어서 주 메뉴 이전의 주 메뉴로 초점이 이동한다. 이 때 자동적으로 하위 메뉴가 펼쳐지며, Tab 키에 의하여 하위 메뉴의 마지막 메뉴로 초점이 이동한다. ‘더보기’ 링크는 Shift + Tab 키로 이동시에 건너뛰게 된다. 화면 낭독 프로그램을 사용하는 경우에는 초점이 주어지는 요소의 텍스트 또는 대체 텍스트를 읽어주어야 한다.
전체적인 기능을 비교해 보면, 롤오버에 의한 가로 탭 메뉴가 Enter 키를 이용한 가로 탭 메뉴에 비하여 화면 구성과 화면 낭독 프로그램과의 관계 면에서 더 직관적이다.
//HTML Document
<head>
<title>가로 탭 메뉴 Type2</title>
<link rel="stylesheet" href="./common/style.css"
type="text/css" />
<script type="text/javascript" src="./common/script.js"></script>
</head>
<body>
<div id="TabMenu">
<div class="TabNoticeStyle">
<a href="#TabNotice0">
<img src="./img/menua_off.gif" alt="공지사항" /></a>
<ul id="TabNotice0">
<li><a href="./notice.html">광주지방 정부청사 금융기관 선정 결과</a></li>
<li><a href="./notice.html">행정안전부 겨울방학 대학생...</a></li>
<li><a href="./notice.html">2008년도 공무원연금운영위원회...</a></li>
<li><a href="./notice.html">2007년도 제5회 공무원연금운영...</a></li>
<li><a href="./notice.html">생활공감정책 국민아이디어 공모...</a></li>
</ul>
<a id="TabNotice0More" href="./notice.html" class="more">
<img src="./img/btn_more.gif" alt="공지사항 더보기" /></a>
</div>
..
</div>
<script type="text/javascript">
var TabMenu1 = new fnTabMenu_Type1;
TabMenu1.MenuName = "TabMenu";
TabMenu1.DivName = "TabNotice";
TabMenu1.fnName = "TabMenu1";
TabMenu1.Start();
</script>
</body>
// JavaScript Document
function fnTabMenu_Type1() {
this.CurrentMenu = 0;
currentTab = 0;
this.Start = function() {
this.MenuBox=document.getElementById(this.MenuName)
.getElementsByTagName("ul");
this.MenuLength=this.MenuBox.length;
this.MenuLayer=document.getElementById(this.MenuName)
.getElementsByTagName("div");
for(var i=0; i<this.MenuLength; i++){
this.MenuLink=this.MenuLayer.item(i).getElementsByTagName("a")[0];
this.MenuLinkBtn=this.MenuLink.getElementsByTagName("img")[0];
if( i == this.CurrentMenu ){
document.getElementById(this.DivName+i).style.display="block";
document.getElementById(this.DivName+i+"More").style.display = "block";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_off.", "_on.");}
else {document.getElementById(this.DivName+i).style.display="none";
document.getElementById(this.DivName+i+"More").style.display="none";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_on.", "_off.");}
this.MenuLink.i = i;
this.MenuLink.fnName = this.fnName;
this.MenuLink.onmouseover = this.MenuLink.onfocus
= function() {eval( this.fnName +".fnMouseOver(" + this.i + ")") }
}
}
this.fnMouseOver = function(val) {
isBack = false;
if(currentTab > val){isBack = true;}
currentTab = val;
for (var i=0; i<this.MenuLength; i++){
this.MenuLink=this.MenuLayer.item(i).getElementsByTagName("a")[0];
this.MenuLinkBtn=this.MenuLink.getElementsByTagName("img")[0];
if(i == val){document.getElementById(this.DivName+ i).style.display="block";
document.getElementById(this.DivName+i+"More").style.display = "block";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_off.", "_on.");}
else{document.getElementById(this.DivName+i).style.display = "none";
document.getElementById(this.DivName+i+"More").style.display="none";
this.MenuLinkBtn.src=this.MenuLinkBtn.src.replace("_on.", "_off.");}
// 하위 메뉴의 제일 마지막부터 차례로 이동하는 부분
// 다음의 3줄을 빼면 메인 메뉴로만 이동합니다.
if(isBack && i== val) {this.MenuLayer.item(i).getElementsByTagName("a")
[this.MenuLayer.item(i).getElementsByTagName("a").length-2].focus();
}
}
}
}
웹의 힘은 그것의 보편성에 있다. 장애에 구애없이 모든 사람이 접근할 수 있는 것이 필수적인 요소이다.
(The power of the Web is in its universality, Access by everyone regardless of disability is an essential aspect.)
팀 버너스 리 경 - 웹의 창시자 (Tim Berners - Lee , W3C Director and inventor of the World Wide Web)