라이브러리 없이 tab(탭) 컴포넌트 구현하기
UI 라이브러리를 사용하지 않고 나만의 custom 탭 컴포넌트를 구현해 보겠습니다.
Environment
- HTML
- Javascript
- SCSS
Thirdparty
- jquery
설계
구현할 탭의 구조는 아래 그림을 참고해 주세요.
tab 컴포넌트라고 정의하여 wrap 합니다.
▪️head영역
사용자가 클릭할 수 있는 tab의 제목 영역입니다.
제목 요소들은 성질이 같으므로 리스트라고 생각할 수 있습니다.
현재 보이고 있는 panel에 따라 head에 선택되었다는 식별자 인디케이터를 통해 구분할 수 있도록 합니다.
▪️ panel 영역
tab의 내용이 구현되는 영역입니다.
최초 진입 시 첫 번째 panel을 제외한 요소들은 숨김 처리합니다.
사용자의 head click 동작을 통해 각 panel이 보이거나 숨겨집니다.
구현
▪️ 퍼블리싱
<div class="tab-wrap">
<div class="tab-head">
<ul class="tab-list">
<li class="active" data-target="tab1">tab 1</li>
<li data-target="tab2">tab 2</li>
<li data-target="3">tab 3</li>
</ul>
</div>
<div class="tab-panel">
<div class="active" data-tab="tab1">
첫번째 탭 내용
</div>
<div data-tab="tab2">
두번째 탭 내용
</div>
<div data-tab="tab3">
세번째 탭 내용
</div>
</div>
</div>
head, panel 리스트 중 현재 보이고 있는 요소를 식별하기 위한 인디케이터로 active class를 사용합니다.
head의 data-target 속성으로 해당 head 요소에 맵핑되는 panel 요소의 data-tab 속성을 정의합니다.
▪️ CSS
색상, 너비 등의 원하는 css를 자유롭게 추가하세요.
.tab-wrap {
.tab-head .tab-list {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.tab-list > li {
font-weight: 500;
color: #666;
background-color: #FAFAFA;
border-top: 1px solid #EBEBEA;
border-bottom: 1px solid #EBEBEA;
cursor: pointer;
&:first-of-type {
border-left: 1px solid #EBEBEA;
}
&:not(:first-of-type) {
border-right: 1px solid #EBEBEA;
}
&.active {
color: #D90479;
background-color: #FFF;
border-left: 1px solid #EBEBEA;
border-right: 1px solid #EBEBEA;
border-bottom-color: #FFF;
}
}
.tab-panel {
margin-top: -1px;
border-top: 1px solid #EBEBEA;
& > *:not(.active) {
display: none;
}
}
}
▪️ 이벤트 바인딩
head 요소 클릭 이벤트 발생 시 실행될 click event handler 메소드를 구현하고 요소에 바인딩합니다.
handler 구현하기
handler 메소드는 아래의 step으로 구현됩니다.
- head wrap 요소에 접근하여 panel wrap 요소를 찾습니다.
- 모든 head와 content의 인디케이터(active class)를 삭제합니다.
- 클릭된 head 요소의 data-target 속성값을 구합니다.
- panel 요소들 중 data-target 속성값이 data-tab 속성값과 같은 요소를 찾아 접근합니다.
- 클릭된 head 요소와 찾은 panel 요소에 인디케이터(active class)를 추가합니다.
function onHeadClick(el) {
const jqThis = $(el);
const jqHead = jqThis.closest(".tab-head");
const jqCont = jqHead.siblings(".tab-panel");
// reset active
jqHead.find(".tab-list > *").removeClass("active");
jqCont.find("> *").removeClass("active");
const targetId = jqThis.attr("data-target");
jqThis.addClass("active");
jqCont.find(`[data-tab="${targetId}"]`).addClass("active");
}
요소에 handler 바인딩하기
document ready 시점에 selector로 일괄 바인딩하기
html 요소가 모두 랜더링 된 후 selector를 통해 일괄 바인딩하는 방식으로, 바인딩할 요소가 많을 경우 편리합니다.
$(".tab-wrap .tab-head .tab-list > li").on("click", function(event) {
onHeadClick(this);
});
완성❗
'Utils' 카테고리의 다른 글
각 자릿수별로 1씩 증가하는 숫자 롤링 카운터 만들기 | HTML, Javascript, jQuery (0) | 2024.07.24 |
---|---|
0부터 1씩 증가하는 숫자 롤링 카운터 만들기 | HTML, Javascript, jQuery (0) | 2024.07.19 |
Timer(타이머) 구현하기 | HTML, Javascript, jQuery (0) | 2024.07.14 |
초 단위 시간을 일시분초(ddhhmmss) 단위로 변환하기 | Javascript (0) | 2024.07.11 |
Custom Accordion(아코디언) 컴포넌트 구현하기 | HTML, Javascript, jQuery (0) | 2024.07.04 |