자바스크립트를 사용해서 정말 간단하게 아코디언 메뉴를 만드는 방법을 기록한다.
미리보기
HTML
<ul>
<li class="on">
<button class="button">menu1</button>
<p id="menu1" class="content">description</p>
</li>
<li>
<button class="button">menu2</button>
<p id="menu2" class="content">description</p>
</li>
<li>
<button class="button">menu3</button>
<p id="menu3" class="content">description</p>
</li>
<li>
<button class="button">menu4</button>
<p id="menu4" class="content">description</p>
</li>
</ul>
꼭 ul>li
태그로 하지 않아도 된다.
중요한건 class="on"
, 버튼을 눌렀을 때 부모 태그에 on class를 추가한다.
코드상에선 기본으로 on class가 추가되어 있지만, 빠져도 상관없다.
버튼의 경우 <a>
, <button>
중 어느것을 사용할지 고민했는데 이번엔 <a>
태그를 사용했다.
모종의 이유로 브라우저가 CSS, JS가 출력되지 않는 경우 A 태그의 엥커 이동 기능이 작동되게 하기 위함이다.
+ 2022-10-06 내용 추가
접근성을 지키려면 페이지 이동이 발생하는 <a>
태그 대신, <button>
태그를 사용하라고 한다.
무언가를 만들었을 때 접근성을 알고싶다면 부트스트랩 사이트를 참고하면 아주 좋다.
⛔️ 주의사항1
div로 버튼을 만들지 말자.
div로 만들면 키보드의 “Tab”으로 버튼에 focus 하는게 불가능하기 때문이다.
⛔️ 주의사항2<a>
태그 안에는 <div>
, <span>
, … 등등 비교적 자유롭게 태그가 포함할 수 있지만, <button>
태그 안에는 블록 태그는 포함하면 안되고 인라인 태그만 사용해야한다. (참고)
CSS
ul {
display: flex;
flex-direction: column;
gap: 16px;
margin: 0;
padding: 0;
max-width: 500px;
width: 100%;
list-style: none;
}
li {
.button {
display: block;
padding: 20px;
width: 100%;
color: #000;
text-align: left;
background-color: #ddd;
border: 0;
cursor: pointer;
}
.content {
display: none;
margin: 0;
padding: 20px;
background-color: #fff;
border-top: 1px solid #ddd;
}
&.on {
.button {
background-color: #fff;
font-weight: bold;
}
.content {
display: block;
}
}
}
ul
의 스타일은 모양을 잡아주기 위해 추가했기 때문에 크게 신경쓰지 않아도 된다. li
안의 스타일을 커스텀 해서 사용하면 된다.
마크업을 변경했다면 스타일도 함께 변경하는걸 잊지말자.
JavaScript
const buttons = document.querySelectorAll('.button');
buttons.forEach(function(button, index) {
button.addEventListener('click', function(e) {
e.preventDefault();
this.parentNode.classList.toggle('on');
buttons.forEach(function(button2, index2) {
if ( index !== index2 ) {
button2.parentNode.classList.remove('on');
}
});
});
});
간단하게 .button
을 전부 가져와서 JavaScriot forEach
를 사용해 반복문을 돌렸다.
반복되는 모든 버튼에 클릭 이벤트를 추가했고 preventDefault();
로 기본 클릭 이벤트를 제거했다.
그리고 클릭할 때 마다 나(this
)에게 on
class를 넣었다 뺄 수 있게 toggle 로 했다.
마지막으로 반복문 안에 다시 버튼 전체에 대한 반복문을 돌려서, 지금 클릭한 버튼의 index와 일치하지 않은 index를 가진 모든 버튼에서 on
class를 제거한다.