Accordion Control

Accordion menu를 컨트롤 하는 인터랙션(Interaction)을 구현합니다.

목적

.AccordionItem.AccordionItem--open 상태 클래스를 추가/제거해서 .AccordionHead를 클릭했을 때 .AccordionBody가 open/close되는 인터랙션을 구현한다.

<div class="AccordionItem">
<!-- AccordionItem--open 본문 펼침 상태 클래스 -->
  <dt class="AccordionHead">넷플릭스란 무엇인가요? <button type="button" class="resetButton AccordionButton"><img src="./assets/plusIcon.svg" alt="펼침" width="24" height="24" /></button></dt>
  <dd class="AccordionBody">
    <p>넷플릭스는 각종 수상 경력에 빛나는 TV 프로그램, 영화, 애니메이션, 다큐멘터리 등 다양한 콘텐츠를 인터넷 연결이 가능한 수천 종의 디바이스에서 시청할 수 있는 스트리밍
      서비스입니다.</p>
    <p>저렴한 월 요금으로 일체의 광고 없이 원하는 시간에 원하는 만큼 즐길 수 있습니다. 무궁무진한 콘텐츠가 준비되어 있으며 매주 새로운 TV 프로그램과 영화가 제공됩니다.</p>
  </dd>
</div>
Accordion Control 예시

설계

변수 설정

사용된 기능

방법

  • .AccordionItem'click' 이벤트를 적용한다.

  • 'click' 했을 때, classList.contains() 메서드를 사용해서 .AccordionItem--open가 존재하는지 확인한다.

  • 클릭 할 때마다 open/close를 반복해야 하기 때문에 open 상태 클래스가 존재 하지 않는다면 classList.add()를 사용해서 추가, 존재한다면 classList.remove() 메서드를 사용해서 제거한다.

처음에 작성한 코드

문제점 발견

  • 문제 : 어떤 Item을 클릭해도 첫 번째 Item만 동작이 되었다.

    • 원인 : 첫 번째 .AccordionItem만 찾아왔기 때문이다.

  • 문제 : e.target을 사용해서 이벤트가 걸린 요소를 확인 하지 않았다. 그러다 보니 계속 밖에서만 .AccordionItem 요소에 접근하려고 하고 안에서 접근할 생각을 하지 못했다.

    • 원인 : .AccordionItem에 이벤트를 걸었기 때문에 e.target이 당연히 .AccordionItem라고 생각했다. handleToggleAccordionBodye.target.AccordionButton이다.

handleToggleAccordionBody의 e.target

개선 (1)

Node.parentNode 사용하기

.AccordionButton.AccordionItem의 자식요소입니다. 자식요소에서 부모요소에 접근하는 Node.parentNode을 사용하여 클릭한 요소의 부모요소에 접근합니다.

handleToggleAccordionBody의 e.target.parentNode.parentNode

Node.parentNod는 인접한 부모요소를 찾기 때문에 부모의 부모를 찾으려면 .parentNode.parentNode으로 작성한다.

개선 (2)

Element.closest() 사용하기

Node.parentNode 보다 더 개선된 메서드 사용합니다. Element.closest()은 선택한 요소에서 인접한 부모요소부터 클래스 이름이 일치하는 부모요소를 찾는다.

개선 (3)

forEach 사용하기

for문 대신 유사배열인 .AccordionItem을 배열화하여 forEach() 메서드를 사용합니다.

개선 (4)

add()/ remove() 메서드 대신 classList.toggle() 메서드를 사용합니다. classList.toggle()는 인자에 전달된 클래스 이름의 유무를 확인하고 만약 있다면 선택된 요소에 제거하고 없다면 제거하는 기능을 하는 메서드입니다. 즉, toggle() 메서드는 contains(), add(), remove() 메서드의 기능을 한 번에 수행합니다.

개선 (5)

Element.closest()에서 null이 반환되는 경우 오류를 방지하기

Element.closest()

closest() 메서드는 element node에 사용이 가능한 메서드입니다. 메서드에 전달된 클래스 이름과 일치하는 가장 가까운 부모가 있을 때 부모 노드를 반환하는 메서드 입니다. 단, 일치하는 부모노드가 없을 경우 null을 반환합니다.

null을 반환하기 때문에 조건문에서 사용이 가능합니다. null = false, 일치하는 노드가 있을 경우 = true 를 반환합니다.

null이 반환 됐을 때 오류 발생

논리 연산자를 사용하기

조건문 사용하기

결론

주의

  • 메서드를 사용하기 전에 꼭 브라우저 호환성을 확인하기

  • addEventListener를 사용할 때는 e.target을 사용해서 이벤트가 걸려있는 요소 확인하기

  • 코드를 작성하고 나서 리팩토링하는 작업을 꼭 한다.

    • 불필요한 코드(예, 주석, console.log() 등)을 정리하고 개선할 사항이 있는지 확인한다.

Last updated

Was this helpful?