★최종 결과물
-
Question 1
How to use this?
-
Question 2
How to use this?
-
Question 3
How to use this?
-
Question 4
How to use this?
1. HTML
<div class="inner_body">
<ul>
<li class="faq_block js-faq_block">
<div class="faq_header">
<h3>Question 1</h3>
<button type="button"><i class="fa-regular fa-square-plus"></i></button>
</div>
<div class="faq_body">
<p>How to use this?</p>
</div>
</li>
<li class="faq_block js-faq_block">
<div class="faq_header">
<h3>Question 2</h3>
<button type="button"><i class="fa-regular fa-square-plus"></i></button>
</div>
<div class="faq_body">
<p>How to use this?</p>
</div>
</li>
<li class="faq_block js-faq_block">
<div class="faq_header">
<h3>Question 3</h3>
<button type="button"><i class="fa-regular fa-square-plus"></i></button>
</div>
<div class="faq_body">
<p>How to use this?</p>
</div>
</li>
<li class="faq_block js-faq_block">
<div class="faq_header">
<h3>Question 4</h3>
<button type="button"><i class="fa-regular fa-square-plus"></i></button>
</div>
<div class="faq_body">
<p>How to use this?</p>
</div>
</li>
</ul>
</div>
<script>
const faqs = document.querySelectorAll('.js-faq_block');
faqs.forEach(faq => { new FAQ(faq); });
</script>
2. CSS
.inner_body {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 400px;
padding: 50px 0;
background: #222;
font-family: 'Poppins', sans-serif;
position: relative;
}
.faq_block {
display: flex;
flex-direction: column;
background-color: #fff;
;
min-width: 480px;
}
.faq_block+.faq_block {
margin-top: 10px;
}
.faq_header {
display: flex;
justify-content: space-between;
padding: 10px;
}
.faq_header h3 {
margin: 0;
padding: 0;
}
.faq_header button {
border: none;
background-color: transparent;
cursor: pointer;
}
.faq_header button i {
font-size: 18px;
color: #111;
}
.faq_body {
max-height: 0;
overflow: hidden;
background-color: #eee;
transition: max-height 0.3s ease-in-out;
padding: 0 10px;
}
3. JS
class FAQ {
constructor(target) {
this.target = typeof target === 'string' ? document.querySelector(target) : target;
this.faqBody = this.target.querySelector('.faq_body');
this.maxHeight = `${this.faqBody.scrollHeight}px`;
this.toggleBtn = this.target.querySelector('button');
this.opened = false;
this.init();
}
init() {
this.toggleBtn.addEventListener('click', () => {
this.toggleButton();
});
}
toggleButton() {
const buttonIcon = this.toggleBtn.querySelector('i');
if (this.opened) {
buttonIcon.classList.remove('fa-square-minus');
buttonIcon.classList.add('fa-square-plus');
this.faqBody.style.maxHeight = '0';
this.opened = false;
} else {
buttonIcon.classList.remove('fa-square-plus');
buttonIcon.classList.add('fa-square-minus');
this.faqBody.style.maxHeight = this.maxHeight;
this.opened = true;
}
}
}
init()
faq 객체 생성 시 해당 DOM 내부의 button에 toggleButton() 메서드를 연결
toggleButton()
faq 객체의 여닫음을 제어하는 매서드.
this.opened값을 이용하여 아이콘 변경 및 maxHeight를 변경해 준다.
여기서 maxHeight값은 this.faqBody의 scrollHeight를 사용했다.
4. 추후 발전 방향
faq item DOM에 특정 속성 추가로 초기에 열려있는 상태 만들기
하나의 faq item만 열리게 하기