2007. 4. 18. 15:08
Programing/HTML/JavaScript/CSS
이 포스팅에서 '탭'이라함은 파이어폭스나 IE7에서 쓰이는 탭브라우징의 그 '탭'과 같은 의미이다.
다음 그림을 보면 쉽게 이해가 갈 것이다.
컨텐츠가 표시되는 영역은 모든 탭이 똑 같다.
여러 컨턴츠 레이어들이 겹쳐져 있는 상태에서 선택된 탭에 해당하는 컨텐츠만 사용자에게 보여주는 것이다.
보통 이 탭기능을 웹에 표현하는 방법으로 이미지를 주로 쓴다.
이미지로 표현하는것이 미관상 좋고 만들기도 수월하기 때문인데, CSS 와 javascript 로 구현하는것도 가능하다.
심플한 텍스트 기반 페이지에 탭기능을 추가하고 싶다면 주목!
다음과 같은 탭을 만들어 보겠다.
오늘 이걸 하느라 아침 시간을 다 보냈다....내공부족...
tab1 ~ tab3 까지 총 세개의 탭은 각각 content1 ~ content3 까지 자기만의 컨텐츠를 갖고 있다.
tab을 누르면 활성화된 탭과 컨텐츠 레이어는 배경색이 흰색으로 바뀌고 활성상태에서 비활성 상태로 전환되는 탭은 배경색이 회색으로 바뀐다.
코드를 살펴보도록 하겠다.
model은 레이어의 레퍼런스를 담을 배열 객체이다.
매번 각 레이어 객체를 찾아야 하는 불편을 덜기 위해 사용했다.
이제 본격적으로 javascript를 구현해보자.
onload 시에 호출 되는 init() 함수와 그에 따른 몇개의 함수가 필요하다.
function switch_execute(layer){
var visible_tab_top = -1;
var hidden_tab_top = 0;
if(window.navigator.appName.indexOf('Explorer') > -1){
visible_tab_top++;
hidden_tab_top++;
}
for(var i=0,max=model.length; i<max; i++){
var tab = get_tab_element(model[i]);
var content = get_content_element(model[i]);
if(model[i] == layer){
model[i].style.zIndex = 99;
tab.style.top = visible_tab_top;
tab.style.backgroundColor = '#FFFFFF';
content.style.backgroundColor = '#FFFFFF';
}else{
model[i].style.zIndex = 0;
tab.style.top = hidden_tab_top;
tab.style.backgroundColor = '#EEEEEE';
content.style.backgroundColor = '#EEEEEE';
}
}
}switch_execute() 함수는 주어진 레이어를 활성화 시키고 나머지 레이어를 비활성화 시키는 일을 한다.
visible_tab_top과 hidden_tab_top 값을 브라우져에 따라 달리한 이유는 IE와 Mozila 계열의 렌더링 방식의 차이때문이다.
기본값은 FF를 위한 값이다.
만약 위와 같은 처리를 생략했을 경우 IE에서 는 활성화 된 탭과 그에 해당하는 컨텐츠 레이어 사이의 경계선이 그대로 남게 되고 FF에서는 탭의 좌우 경계선이 컨텐츠 레이어 안으로 비집고 들어오는 모습을 보게 될 것이다.
역시 IE와 FF의 차이가 있기 때문에 firstChild, lastChild 를 쓰지 않았다.
속도가 느려지는 일이 발생한다면 위 두함수를 하나로 묶어서 반복문을 하나로 축약해야 할 것이다.
별로 그럴일은 없을것 같지만...
다음 그림을 보면 쉽게 이해가 갈 것이다.
Ariticles,Location log,Key Log 같은 것들이
여러 컨턴츠 레이어들이 겹쳐져 있는 상태에서 선택된 탭에 해당하는 컨텐츠만 사용자에게 보여주는 것이다.
보통 이 탭기능을 웹에 표현하는 방법으로 이미지를 주로 쓴다.
이미지로 표현하는것이 미관상 좋고 만들기도 수월하기 때문인데, CSS 와 javascript 로 구현하는것도 가능하다.
심플한 텍스트 기반 페이지에 탭기능을 추가하고 싶다면 주목!
다음과 같은 탭을 만들어 보겠다.
오늘 이걸 하느라 아침 시간을 다 보냈다....내공부족...
tab1 ~ tab3 까지 총 세개의 탭은 각각 content1 ~ content3 까지 자기만의 컨텐츠를 갖고 있다.
tab을 누르면 활성화된 탭과 컨텐츠 레이어는 배경색이 흰색으로 바뀌고 활성상태에서 비활성 상태로 전환되는 탭은 배경색이 회색으로 바뀐다.
코드를 살펴보도록 하겠다.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Switching Tab </title>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<script type="text/javascript">
<!--
var model = new Array();
function init(){
}
-->
</script>
<style>
.tab{
width: 50px;
height: 20px;
border-top: solid 1px #D9D9D9;
border-right: solid 1px #D9D9D9;
border-left: solid 1px #D9D9D9;
background-color: #EEEEEE;
position: absolute;
z-index: 2;
}
#tab1{
margin-left: 10px;
}
#tab2{
margin-left: 60px;
}
#tab3{
margin-left: 110px;
}
.content{
width: 200px;
height: 50px;
border: solid 1px #D9D9D9;
background-color: #EEEEEE;
position: absolute;
top: 19px;
z-index: 1;
}
#layer1{
top: 50px;
left: 50px;
position: absolute;
}
#layer2{
top: 50px;
left: 50px;
position: absolute;
}
#layer3{
top: 50px;
left: 50px;
position: absolute;
</style>
</head>
<body onload="init()">
<div id="layer1">
<div id="tab1" class="tab">tab1</div>
<div class="content">content 1</div>
</div>
<div id="layer2">
<div id="tab2" class="tab">tab2</div>
<div class="content">content 2</div>
</div>
<div id="layer3">
<div id="tab3" class="tab">tab3</div>
<div class="content">content 3</div>
</div>
</body>
</html>
<html>
<head>
<title> Switching Tab </title>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<script type="text/javascript">
<!--
var model = new Array();
function init(){
}
-->
</script>
<style>
.tab{
width: 50px;
height: 20px;
border-top: solid 1px #D9D9D9;
border-right: solid 1px #D9D9D9;
border-left: solid 1px #D9D9D9;
background-color: #EEEEEE;
position: absolute;
z-index: 2;
}
#tab1{
margin-left: 10px;
}
#tab2{
margin-left: 60px;
}
#tab3{
margin-left: 110px;
}
.content{
width: 200px;
height: 50px;
border: solid 1px #D9D9D9;
background-color: #EEEEEE;
position: absolute;
top: 19px;
z-index: 1;
}
#layer1{
top: 50px;
left: 50px;
position: absolute;
}
#layer2{
top: 50px;
left: 50px;
position: absolute;
}
#layer3{
top: 50px;
left: 50px;
position: absolute;
</style>
</head>
<body onload="init()">
<div id="layer1">
<div id="tab1" class="tab">tab1</div>
<div class="content">content 1</div>
</div>
<div id="layer2">
<div id="tab2" class="tab">tab2</div>
<div class="content">content 2</div>
</div>
<div id="layer3">
<div id="tab3" class="tab">tab3</div>
<div class="content">content 3</div>
</div>
</body>
</html>
model은 레이어의 레퍼런스를 담을 배열 객체이다.
매번 각 레이어 객체를 찾아야 하는 불편을 덜기 위해 사용했다.
이제 본격적으로 javascript를 구현해보자.
onload 시에 호출 되는 init() 함수와 그에 따른 몇개의 함수가 필요하다.
function init(){
var layer1 = document.getElementById('layer1');
var layer2 = document.getElementById('layer2');
var layer3 = document.getElementById('layer3');
model.push(layer1);
model.push(layer2);
model.push(layer3);
for(var i=0,max=model.length; i<max; i++){
set_event_listener(model[i],'mouseover','switching_tab');
}
switch_execute(layer1);
}
init()함수는 각 레이어의 레퍼런스를 배열 model 에 추가하고 이벤트를 걸어준 다음 첫번째 레이어를 활성화 시킨다.var layer1 = document.getElementById('layer1');
var layer2 = document.getElementById('layer2');
var layer3 = document.getElementById('layer3');
model.push(layer1);
model.push(layer2);
model.push(layer3);
for(var i=0,max=model.length; i<max; i++){
set_event_listener(model[i],'mouseover','switching_tab');
}
switch_execute(layer1);
}
function set_event_listener(obj,evt_type,callback){
if(window.event){
obj.attachEvent('on' + evt_type,eval(callback));
}else{
obj.addEventListener(evt_type,eval(callback),false);
}
}
set_event_listener() 함수는 주어진 객체에 evt_type 형식의 이벤트를 걸어준다.if(window.event){
obj.attachEvent('on' + evt_type,eval(callback));
}else{
obj.addEventListener(evt_type,eval(callback),false);
}
}
function switching_tab(e){
var target;
if(window.event){
target = window.event.srcElement;
}else{
target = e.target;
}
switch_execute(target.parentNode);
}
switching_tab() 함수는 이벤트가 발생할때 호출 되며 이벤트가 일어난 객체를 switch_execute 로 보내는 역할을 한다.var target;
if(window.event){
target = window.event.srcElement;
}else{
target = e.target;
}
switch_execute(target.parentNode);
}
function switch_execute(layer){
var visible_tab_top = -1;
var hidden_tab_top = 0;
if(window.navigator.appName.indexOf('Explorer') > -1){
visible_tab_top++;
hidden_tab_top++;
}
for(var i=0,max=model.length; i<max; i++){
var tab = get_tab_element(model[i]);
var content = get_content_element(model[i]);
if(model[i] == layer){
model[i].style.zIndex = 99;
tab.style.top = visible_tab_top;
tab.style.backgroundColor = '#FFFFFF';
content.style.backgroundColor = '#FFFFFF';
}else{
model[i].style.zIndex = 0;
tab.style.top = hidden_tab_top;
tab.style.backgroundColor = '#EEEEEE';
content.style.backgroundColor = '#EEEEEE';
}
}
}
visible_tab_top과 hidden_tab_top 값을 브라우져에 따라 달리한 이유는 IE와 Mozila 계열의 렌더링 방식의 차이때문이다.
기본값은 FF를 위한 값이다.
만약 위와 같은 처리를 생략했을 경우 IE에서 는 활성화 된 탭과 그에 해당하는 컨텐츠 레이어 사이의 경계선이 그대로 남게 되고 FF에서는 탭의 좌우 경계선이 컨텐츠 레이어 안으로 비집고 들어오는 모습을 보게 될 것이다.
function get_tab_element(model){
var child = model.childNodes;
for(var i=0,max=child.length; i<max; i++){
if(child[i].nodeType == 1 && child[i].className == 'tab'){
return child[i];
}
}
}
function get_content_element(model){
var child = model.childNodes;
for(var i=0,max=child.length; i<max; i++){
if(child[i].nodeType == 1 && child[i].className == 'content'){
return child[i];
}
}
}
위 두 함수는 레이어에서 탭과 컨텐츠 영역을 추출하는 용도로 쓰인다.var child = model.childNodes;
for(var i=0,max=child.length; i<max; i++){
if(child[i].nodeType == 1 && child[i].className == 'tab'){
return child[i];
}
}
}
function get_content_element(model){
var child = model.childNodes;
for(var i=0,max=child.length; i<max; i++){
if(child[i].nodeType == 1 && child[i].className == 'content'){
return child[i];
}
}
}
역시 IE와 FF의 차이가 있기 때문에 firstChild, lastChild 를 쓰지 않았다.
속도가 느려지는 일이 발생한다면 위 두함수를 하나로 묶어서 반복문을 하나로 축약해야 할 것이다.
별로 그럴일은 없을것 같지만...
'Programing > HTML/JavaScript/CSS' 카테고리의 다른 글
Javascript 객체 들여다보기 (0) | 2007.05.22 |
---|---|
What is the Flapjax. (0) | 2007.04.19 |
JavaScript: 세상에서 가장 오해가 많은 프로그래밍 언어 (2) | 2007.04.06 |
Javascript 의 Object : new Object() ?===? {} (0) | 2007.04.06 |
AJAX 실전 #2 - 주소록 구현 준비 (1) | 2007.03.30 |