All'alba vincerò

At dawn, I will win!

Toy Projects

[Javascript] Question

나디아 Nadia 2024. 3. 6. 15:44

 

Question

: 질문 상자(box)를 누르면 내용(content)을 보여주는 바가 내려간다.



사용 언어

- HTML
- CSS
- Javascript

 


구조

- index.html - 전체 구조
- index.js - 기능 구현
- main.css - 전체 디자인



 

코드

 

구현 계획

  1. 버튼 html, css 생성
  2. 버튼 누르면 서브 메뉴 열리게 구현 (js)
    • 버튼 누르면 서브 메뉴 열고 닫히게 토글 생성
    • 서브 메뉴가 열려있으면 (if(max-height)) 서브메뉴 닫고(max-height == null) 닫혀있으면 (max-height + "px")
    • css에서 transition에 시간 설정

 

기능 구현

  1. for문을 이용하여 3개의 버튼에 토글 기능 부여
  2. 버튼의 다음 요소(=내용content)를 가지고 온다. (nextElementSibling)
  3. 요소의 최대 높이를 통해 열려있는지 확인한다.(.style.maxHeight)
    (1) 내용이 열려있으면(content.style.maxHeight)
    내용을 닫는다. (content.style.maxHeight = null;)
    (2) 내용이 닫혀있으면
    내용을 연다. (= 내용의 최대 높이를 스크롤 높이로 만든다.
    maxHeight = content.scrollHeight + "px")
for (let i = 0; i < button.length; i++) {
    button[i].addEventListener("click", function () {
        this.classList.toggle("show");

        let content = this.nextElementSibling;
        if (content.style.maxHeight) {
            content.style.maxHeight = null;
        } else {
            content.style.maxHeight = content.scrollHeight + "px";
        }
    });
}

 

 

 

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="main.css">

    <style>
        @import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,300;0,400;0,700;0,900;1,300;1,400;1,700;1,900&display=swap');
    </style>
</head>

<body style="background-color: hsl(210, 36%, 96%)">

    <div id="question">
        <p>Questions</p>
    </div>

    <div class="container">
        <button type="button" class="btn">Do You Accept All Major Credit Cards?</button>
        <div class="content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
        </div>
    </div>
    <div class="container2">
        <button type="button" class="btn">Do You Suppport Local Farmers?</button>
        <div class="content">
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
        </div>
    </div>
    <div class="container3">
        <button type="button" class="btn">Do You Use Organic Ingredients?</button>
        <div class="content">
            <p>Lorem ipsum dolor sit ametLorLorem ipsum dolor sit ametem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet, consectetur adipisicing elit. </p>
        </div>
    </div>
    <script src="main.js">
    </script>
</body>
</html>

 

 

 

index.js

let button = document.getElementsByClassName("btn"); // 버튼 변수 생성

for (let i = 0; i < button.length; i++) {
    button[i].addEventListener("click", function () {
        this.classList.toggle("show");

        let content = this.nextElementSibling;
        if (content.style.maxHeight) {
            content.style.maxHeight = null;
        } else {
            content.style.maxHeight = content.scrollHeight + "px";
        }
    });
}

 

 

 

main.css

#question {
    color: #050505;
    font-family: "Merriweather", serif;
    font-weight: 400;
    font-style: italic;
    font-size: 35px;
    text-align: center;
    font-weight: 360;

    padding-top: 100px;
    margin: -60px;
}

/* 버튼 */
.btn { 
    background-color: #ffffff;
    color: #050505;

    font-size: 16px;
    font-family: "Merriweather", serif;
    font-weight: 400;
    font-style: italic;

    cursor: pointer;
    padding: 30px;

    width: 100%;

    border-radius: 10px;
    border: none;
    text-align: center;
    outline: none;
    box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);

  }

/* 버튼에 마우스 오버 시 색상 변경 */
.btn:hover { 
    background-color: #ededed;
}

/* 버튼 토글 */
.show { 
    display: block;
}

/* 내용 */
.content {
    background-color: white;
    font-family: "Merriweather", serif;
    font-weight: 400;
    font-style: italic;
    font-size: 13px;
    text-align: center;

    max-height: 0;
    overflow: hidden;

    box-shadow: 1px 2px 1px rgb(172, 172, 172), 1px 1px 0px rgb(237, 237, 237);
    border-radius: 10px;
    transition: max-height 0.2s ease-out;
}

  /* 버튼 위치 */
  .container {
    /* padding: top, right, bottom, left */
    padding: 70px 50px 8px 50px;
  }

  .container2 {
    padding: 20px 50px 20px 50px;
  }

  .container3 {
    padding: 10px 50px 30px 50px;
  }


  /* 버튼 옆에 아이콘(+, -) */
  .btn::after {
    content: '\02795'; /* (+) 유니코드 */
    font-size: 13px;
    color: rgb(157, 23, 23);
    float: right;
    margin-left: 10px;
  }
  
  .show::after {
    content: "\2796"; /* (-) 아이콘 유니코드 */
  }

 

 


 

아쉬운 점

 

 

1. 하단의 내용 바가 내려가는 모양이 이상하다.

  • 버튼 박스의 높이가 조절되며 열리는 것이 아니라 내용 박스가 따로 버튼 박스 아래에 생기는 방식으로 구현되었다.
  • 버튼의 height를 기본값 → 결과값(내용 바가 내려간 값)으로 변경하면 되지 않을까 싶었으나 시간이 부족하여 구현하지 못했다.이로 인해 버튼 박스 안에 버튼과 하단 내용 바를 구분하는 구분선을 넣지 못했다.
    링크를 참고해서 다시 만들어보고 싶다. 
    https://kasterra.github.io/making-performant-collapsing-animation/

 

2. 박스 너비가 고정된 상태가 아닌 창 크기에 따라 달라진다.

  • 전체 창에서 보면 너비가 너무 넓어진다.

 

3. 박스 아무 곳을 눌러도 하단 바가 열린다.

  • 버튼 박스가 아닌 오른쪽의 (+)아이콘만 선택해서 하단 내용 바를 열 수 있게 해야 한다.

 

 


 

깃허브

https://github.com/kwonboryong/study_of_FE/tree/main/Question

 

 




출처

https://www.w3schools.com/howto/howto_js_collapsible.asp
https://kasterra.github.io/making-performant-collapsing-animation/

 

배운것
https://limsw.tistory.com/m/108
https://aljjabaegi.tistory.com/m/548
https://nykim.work/71
https://poiemaweb.com/css3-transition