본문 바로가기

Utils

Custom Accordion(아코디언) 컴포넌트 구현하기 | HTML, Javascript, jQuery

Custom Accordion(아코디언) 컴포넌트 구현하기 ❘ HTML, Javascript, jQuery

라이브러리 없이 accordion(아코디언) 컴포넌트 구현하기

 

UI 라이브러리를 사용하지 않고 나만의 custom 아코디언 컴포넌트를 구현해 보겠습니다.


Environment

  • HTML
  • Javascript
  • SCSS

Thirdparty

  • jquery
  • fontawesome

설계

구현할 아코디언의 구조는 아래와 같습니다.

accordion structure(아코디언 구조)

 

accordion 컴포넌트라고 정의하여 wrap 합니다.

 

▪️head 영역

아코디언 전체의 제목입니다.

 

▪️ body 영역

실제 아코디언이 구현될 wrap입니다.

아코디언에 포함되는 각 item은 성질이 같은 리스트의 개념으로 생각합니다.

제목 영역은 항상 보이는 요소이며, 내용 영역은 기본 숨김 처리되고 사용자가 toggle 버튼을 클릭함으로써 보이거나 숨겨집니다.

내용 영역은 없는 경우도 있으며, 내용 영역이 있는 경우에만 toggle 버튼을 구현합니다.


구현

▪️ 퍼블리싱

<div class="accr-wrap">
    <div class="accr-head">제목</div>
    <ul class="accr-body">
        <li>
            <div class="accr-title">
                내용 없는 항목
            </div>
        </li>
        <li>
            <div class="accr-title">
                내용 있는 항목
                <span class="icon">내용보기</span>
            </div>
            <div class="accr-cont">
                아코디언내용
            </div>
        </li>
    </ul>
</div>

 

▪️ CSS

원하는 css를 적용하여 구현할 수 있습니다.

.accr-wrap {
  // head 영역
  .accr-head {
    font-weight: bold;
  }

  // 제목 영역
  &.title-icon .accr-title {
    cursor: pointer;
  }

  // 내용 영역
  & > ul.accr-body {
    & > li:has(.accr-cont) {
      .icon {
        cursor: pointer;
        color: red;
      }
      .icon:after {
        content: "\f107";
        font: var(--fa-font-solid);
        font-size: .7em;
        margin-left: 5px;
        vertical-align: middle;
      }
      .accr-cont {
        display: none;
      }
    }

    & > li:has(>.accr-cont.open) {
      .icon:after {
        content: "\f106";
      }
    }
  }
}

 

▪️ 이벤트 바인딩

toggle 버튼 클릭 이벤트 발생 시 실행될 Click Event Handler 메소드를 구현하고 요소에 바인딩합니다.

💡 바인딩(binding)
bind '묶다'라는 의미에서 알 수 있듯, 이벤트가 발생할 요소와 이벤트 발생시 실행될 동작을 연결하는 것입니다.

handler 구현하기

handler 메소드는 아래의 step으로 구현됩니다.

  1. 클릭된 toggle 버튼의 부모 item 요소에 접근하여 자식 요소 중 내용 영역 요소가 있는지 판단합니다.
  2. 내용 영역이 존재한다면 내용 영역의 visible 여부를 판단합니다.
  3. 내용 영역이 숨김 상태라면 보임 처리하고 구분자 class를 추가합니다.
  4. 내용 영역이 보임 상태라면 숨김 처리하고 구분자 class를 삭제합니다.
function onToggleHandler(el) {
    const jqThis = $(el);
    const jqCont = jqThis.hasClass(".accr-title") ? jqThis : jqThis.closest("li").find(".accr-cont");
    if (jqCont !== undefined && jqCont.length > 0) {
        const isVisible = jqCont.is(":visible");

        if (isVisible) {
            jqCont.slideUp();
            jqCont.removeClass("open");
        } else {
            jqCont.slideDown();
            jqCont.addClass("open");
        }
    }
}

 

요소에 handler 바인딩하기

click event가 발생될 요소에 handler를 바인딩합니다.

▶ 방법 1. document.ready 시점에 selector로 일괄 바인딩하기

html 요소가 모두 랜더링 된 후 시점에 selector로 일괄 바인딩합니다.

바인딩할 요소가 많을 경우 편리합니다.

$(function() {
	// toggle 버튼 selector
	$(".accr-wrap .accr-title > .icon").on("click", function(event) {
    	onToggleHandler(this); // toggle handler 호출
    }
})

 

▶ 방법 2. 요소의 onclick 속성으로 직접 바인딩하기

구현한 onToggleHandler 메소드를 toggle 이벤트가 발생할 버튼에 직접 바인딩합니다.

이벤트 발생한 요소인 this 객체를 파라미터로 전달합니다.

<!-- ... 생략 -->
<div class="accr-title">
    내용 있는 항목
    <span class="icon" onclick="onToggleHandler(this)">내용보기</span>
</div>

완성❗

 

728x90