[JS] 아코디언 게시판 만들기

💡 아코디언 메뉴를 만들어보자!

⭐️ 완성샷

  • 아코디언 게시판을 만들어보자!

🔴 BootStrap 사용하기


  • 부트스트랩 CSS를 이용해 테이블 태그를 꾸며 줄 것이다.
  • 부트스트랩 사이트에서 테이블 CSS 클래스명을 알 수 있다. 나한테 필요한 CSS 디자인을 정하고, 적용하자!
  • 부트스트랩 사용 방법
    • <head> 안에 부트스트랩 cdn을 link 해준다.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">

🟠 HTML


<div class="container">
    <h3 style="text-align: center; padding-top: 50px;">
      FAQ
      <small class="text-muted">with faded secondary text</small>
    </h3>
    <button id="btn-all-close">FAQ ALL Close</button>
    <br>
    <table class="table table-bordered table-striped table-dark table-hover">
      <caption>FAQ List of Articles</caption>
      <thead class="thead-light text-center">
        <tr>
          <th>No</th>
          <th>FAQ Title</th>
          <th>Category</th>
          <th>Date</th>
          <th>Hit</th>
        </tr>
      </thead>
      <tbody class="text-center">
        <tr>
          <td>1</td>
          <td class="text-left" width="50%">
            <div class="panel-faq-container">
              <p class="panel-faq-title">What is Lorem Ipsum?</p>
              <div class="panel-faq-answer">
                <p>Answer (1) ... ↓</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
                  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                  aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
                  dolore eu fugiat nulla pariatur.</p>
                <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                  laborum.</p>
              </div>
            </div>
          </td>
          <td>이용안내</td>
          <td>2032.01.01</td>
          <td>84</td>
        </tr>
        <tr>
          <td>2</td>
          <td class="text-left" width="50%">
            <div class="panel-faq-container">
              <p class="panel-faq-title">Where does it come from?</p>
              <div class="panel-faq-answer">
                <p>Answer (2) ... ↓</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
                  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                  aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
                  dolore eu fugiat nulla pariatur.</p>
                <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                  laborum.</p>
              </div>
            </div>
          </td>
          <td>회원가입</td>
          <td>2032.02.02</td>
          <td>114</td>
        </tr>
        <tr>
          <td>3</td>
          <td class="text-left" width="50%">
            <div class="panel-faq-container">
              <p class="panel-faq-title">Why do we use it?</p>
              <div class="panel-faq-answer">
                <p>Answer (3) ... ↓</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
                  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                  aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
                  dolore eu fugiat nulla pariatur.</p>
                <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                  laborum.</p>
              </div>
            </div>
          </td>
          <td>결제관련</td>
          <td>2032.03.03</td>
          <td>98</td>
        </tr>
        <tr>
          <td>4</td>
          <td class="text-left" width="50%">
            <div class="panel-faq-container">
              <p class="panel-faq-title">Where can I get some?</p>
              <div class="panel-faq-answer">
                <p>Answer (4) ... ↓</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
                  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                  aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
                  dolore eu fugiat nulla pariatur.</p>
                <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                  laborum.</p>
              </div>
            </div>
          </td>
          <td>이용안내</td>
          <td>2032.04.04</td>
          <td>43</td>
        </tr>
        <tr>
          <td>5</td>
          <td class="text-left" width="50%">
            <div class="panel-faq-container">
              <p class="panel-faq-title">The standard Lorem Ipsum passage, used since the 1500s</p>
              <div class="panel-faq-answer">
                <p>Answer (5) ... ↓</p>
                <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
                  et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
                  aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
                  dolore eu fugiat nulla pariatur.</p>
                <p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
                  laborum.</p>
              </div>
            </div>
          </td>
          <td>배송관련</td>
          <td>2032.05.05</td>
          <td>90</td>
        </tr>
        <tr class="bg-info">
          <td colspan=4 class="text-left">자주 묻는 질문 총 합계</td>
          <td>429</td>
        </tr>
      </tbody>
    </table>
  </div>

🟤 table 태그 설명

  • table>(thead>tr>th)+tbody>tr>td
  • tr, th, td만 자기가 원하는 만큼 늘려서 쓰면된다.
  • tr = 행, th, td = 열 이라고 생각하면 된다.

🟤 FAQ Title의 Answer부분 코드 설명

  • div.panel-faq-container>p.panel-faq-title+div.panel-faq-answer>p*3

🟡 CSS


html,body {
  font-family: Helvetica, Arial, sans-serif;
  margin: 0;
}
.panel-faq-container {
  margin-bottom: -16px;
}
.panel-faq-title {
  color: #00eaea;
  cursor: pointer;
}
.panel-faq-answer {
  height: 0;
  overflow: hidden;
  /* 변화가 시작되는 쪽에다가 transition 적용해준다 0 -> 300px 
  왜? 닫기 버튼을 누를 때 변화가 티남 */
  transition: all 1s;
}
#btn-all-close {
  margin-bottom: 10px;
  background-color: #726996;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 10px 25px;
  float: right;
}
#btn-all-close:hover {
  background-color: yellow;
  color: #000;
  transition: all 0.35s;
}
.active {
  display: block;
  /* 높이를 정해줘야지만 transition이 적용됨 */
  height: 300px;
}

🟤 .panel-faq-answer 감추는 방법

  • div.panel-faq-answer을 감추는 방법에는 2가지가 있다.
  1. display:none;을 적용하는 방법
  2. height:0px; overflow:hidden;을 적용하는 방법
  • 나는 2번째 방법을 사용할 것이다.
    display:none;을 적용하고, .active {display:block;} 이런 식으로 코딩하면 나중에 transitiondisplay에는 적용이 안된다. 나는 transition을 적용할 것이기 때문에 2번째 방법을 사용하는 것이다.

🟤 transition

  • 변화가 시작되는 쪽에다가 transition 적용해준다. 0 -> 300px
    btn-all-close 버튼을 누를 때 변화가 티남 (.active에 적용하면 버튼을 눌렀을 때 transition이 적용이 안됨)

🟢 Java Script


window.onload = () => {
  // panel-faq-container
  const panelFaqContainer = document.querySelectorAll(".panel-faq-container"); // NodeList 객체
  
  // panel-faq-answer
  let panelFaqAnswer = document.querySelectorAll(".panel-faq-answer");

  // btn-all-close
  const btnAllClose = document.querySelector("#btn-all-close");
  
  // 반복문 순회하면서 해당 FAQ제목 클릭시 콜백 처리
  for( let i=0; i < panelFaqContainer.length; i++ ) {
    panelFaqContainer[i].addEventListener('click', function() { // 클릭시 처리할 일
      // FAQ 제목 클릭시 -> 본문이 보이게끔 -> active 클래스 추가
      panelFaqAnswer[i].classList.toggle('active');
    });
  };
  
  btnAllClose.addEventListener('click', function() {
    // 버튼 클릭시 처리할 일  
    for(let i=0; i < panelFaqAnswer.length; i++) {
        panelFaqAnswer[i].classList.remove('active');
    };
  });
}

🟤 window.onload 함수

  • 자바스크립트는 html문서가 다 실행되고 나서야 자바스크립트가 동작할 수 있다. 만약 script를 <head>에 위치시켜놨으면 js가 먼저 실행되고 나서 html문서가 실행되기 때문에 js는 html에서 아무것도 받아오지 못한다.
    따라서
  1. <body> 안 맨 끝에 js를 위치하는 방법
  2. window.onload : 다 로드한 다음 실행한다는 뜻의 함수를 쓰는 방법
  • 2가지 방법이 있다. 나는 그 중 window.onload함수를 썼다.

🟤 querySelector

  • querySelector()는 특정 name,id,class를 제한하지 않고 css선택자를 사용하여 요소를 찾음
  • 같은 id 또는 class 일 경우 스크립트의 최상단 요소만 로직에 포함

🟤 querySelectorAll

  • querySelector와 사용 방법은 동일하며 선택자를 선택하여 배열과 비슷한 객체인 nodeList를 반환
  • 반환객체가 nodeList이기에 for문 또는 forEach문을 사용합니다.
  • 아래 코드와 같이 ","를 사용하면 여러 요소를 한번에 가져올 수 있음
    querySelectorAll("#id,.class");

좋은 웹페이지 즐겨찾기