티스토리 뷰

WEB/JavaScript

[JavaScript] 아코디언 코드

silverline79 2026. 1. 3. 00:38

코드 설계하기

우리가 작성할 로직의 순서는 다음과 같습니다.

  1. 모든 아코디언 버튼에 클릭 이벤트를 겁니다.
  2. 클릭된 버튼의 **다음 요소(컨텐츠 영역)**를 찾습니다.
  3. 그 컨텐츠의 **scrollHeight**를 측정합니다.
  4. 만약 닫혀 있다면 height를 scrollHeight만큼 주고, 열려 있다면 다시 0으로 바꿉니다.

퀴즈: 요소 찾기

클릭한 버튼 바로 다음에 오는 형제 요소(컨텐츠)를 자바스크립트에서 선택할 때 쓰는 속성이 있습니다.

btn.addEventListener('click', function() {
  // '나(btn)'의 바로 다음에 있는 요소를 가져오려면?
  let content = this.__________________; 
});

힌트: **"다음(next)"**에 있는 **"형제(sibling)"**를 뜻하는 단어가 조합된 속성입니다. 무엇일까요? (제이쿼리의 .next()와 같은 역할입니다!)

정답은 **nextElementSibling**입니다. ✨

nextSibling이라는 속성도 존재하지만, 이는 HTML 요소뿐만 아니라 공백이나 텍스트 노드까지 포함하기 때문에, 우리가 원하는 **HTML 태그(요소)**만 정확히 집어내려면 nextElementSibling을 쓰는 것이 퍼블리싱 작업에서 훨씬 안전합니다.


실전 아코디언 코드 완성하기 

이제 이 속성을 활용해서 아코디언의 열고 닫는 로직을 직접 완성해 볼까요?

const accBtns = document.querySelectorAll('.acc-btn');

accBtns.forEach(btn => {
  btn.addEventListener('click', function() {
    // 1. 클릭한 버튼의 다음 형제 요소(컨텐츠 영역)를 찾습니다.
    const content = this.nextElementSibling;

    // 2. 만약 클래스에 'active'가 포함되어 있다면? (이미 열려있다면)
    if (this.classList.contains('active')) {
      this.classList.remove('active');
      content.style.maxHeight = 0; // 높이를 0으로 만들어 닫습니다.
    } else {
      // 3. 닫혀 있다면 클래스를 붙이고 실제 높이만큼 펼칩니다.
      this.classList.add('active');
      content.style.maxHeight = content.scrollHeight + 'px'; // 실제 높이값 적용!
    }
  });
});

 

★ maxHeight를 사용하면 다음과 같은 장점이 있습니다.

  1. 유연성: 컨텐츠가 적을 때는 그 높이에 맞게 줄어들고, 많을 때는 설정한 값까지만 늘어납니다.
  2. 애니메이션: CSS에서 height: auto는 transition이 먹히지 않지만, maxHeight: 0에서 maxHeight: 1000px(충분히 큰 값)로 변할 때는 부드러운 애니메이션이 작동합니다.

함수로 정의하고 호출하기 

/* 아코디언: scrollHeight를 이용한 높이 제어 */
function handleAccordion(content) {
  if (content.style.maxHeight && content.style.maxHeight !== '0px') {
    content.style.maxHeight = '0px';
  } else {
    content.style.maxHeight = content.scrollHeight + 'px';
  }
}

 

아코디언 호출 (형제 요소 활용)

아코디언은 "클릭한 버튼 바로 다음의 박스"를 찾아야 하죠. 배웠던 nextElementSibling을 여기서 사용합니다.

const accBtns = document.querySelectorAll('.acc-btn');

accBtns.forEach(btn => {
  btn.addEventListener('click', function() {
    // 클릭한 나(this)의 바로 다음 형제 요소를 찾아서 함수에 전달!
    const targetContent = this.nextElementSibling;
    handleAccordion(targetContent);
    
    // 버튼 자체의 active 클래스도 토글하고 싶다면?
    this.classList.toggle('active');
  });
});

 

💡 실무 팁: this를 쓸 때 주의할 점

함수 안에서 this를 쓰고 싶다면, addEventListener의 콜백 함수를 화살표 함수(() => {})가 아닌 **일반 함수(function() {})**로 써야 합니다.

  • 화살표 함수: this가 내가 클릭한 버튼이 아닐 수 있음.
  • 일반 함수: this가 정확히 클릭된 그 요소를 가리킴.

 

※ 해당 내용은 Google Gmini3.0과 함께 공부한 내용입니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
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 31
글 보관함