WEB/💡 Javascript

[Javascript] 아코디언 메뉴 만들기 (접기/펼치기 기능 구현)

무딘붓 2022. 7. 20. 00:09

자바스크립트로 구현한 접기, 펼치기 기능

<details>, <summary> 태그를 이용해서 편하게 내용을 접고 펼치는 기능을 구현할 수 있지만,

좀 더 다양한 기능 (특정 조건에서 펼치기, 하나만 펼쳐지게 하기 등)이 필요해서 자바스크립트를 이용해서 구현하는 방법을 찾았다.

 

기초적인 내용은 아래 링크를 통해 구현했다.

https://www.w3schools.com/howto/howto_js_collapsible.asp

 

How To Create a Collapsible

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

기본적인 접기/펼치기 기능뿐 아니라 부드럽게 전환되는 효과까지 고려하고 있어 많은 것을 배울 수 있었다.

 

여기에 추가적으로 하나의 메뉴만 펼쳐지게 하기 위한 자바스크립트 코드를 조금 추가하고,

내가 원하는 다른 기능을 추가하기 위해서 작동 방식을 조금 수정했다.

 

하나의 메뉴만 펼쳐지게 하는 방법은 메뉴를 클릭하면 "active" class를 추가하고, 기존에 "active" class를 가진 객체를 찾아 제거하는 방식이다.

 

내용을 펼치고 접는 것은 내용을 담은 태그의 maxHeight를 바꿔주는 방식으로 구현한다. 접혀있는 경우가 0, 펼쳐지는 경우에는 내용물에 맞춰 값을 지정하는 방식이다.

<!DOCTYPE html>
<html>
<head>
    <style>
        .collapsible {
            background-color: #777;
            color: white;
            cursor: pointer;
            padding: 18px;
            width: 100%;
            border: none;
            text-align: left;
            outline: none;
            font-size: 15px;
        }
        .active,
        .collapsible:hover {
            background-color: #555;
        }
        .content {
            padding: 0 18px;
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.2s ease-out;
            background-color: #f1f1f1;
        }
        .collapsible:after {
            content: '\002B';
            color: white;
            font-weight: bold;
            float: right;
            margin-left: 5px;
        }
        .active:after {
            content: "\2212";
        }
    </style>
    
    <script>
        function collapse(element) {
            var before = document.getElementsByClassName("active")[0]               // 기존에 활성화된 버튼
            if (before && document.getElementsByClassName("active")[0] != element) {  // 자신 이외에 이미 활성화된 버튼이 있으면
                before.nextElementSibling.style.maxHeight = null;   // 기존에 펼쳐진 내용 접고
                before.classList.remove("active");                  // 버튼 비활성화
            }
            element.classList.toggle("active");         // 활성화 여부 toggle

            var content = element.nextElementSibling;
            if (content.style.maxHeight != 0) {         // 버튼 다음 요소가 펼쳐져 있으면
                content.style.maxHeight = null;         // 접기
            } else {
                content.style.maxHeight = content.scrollHeight + "px";  // 접혀있는 경우 펼치기
            }
        }
    </script>
</head>

<body>
    <h2>접기/펴기 테스트</h2>
    <button type="button" class="collapsible" onclick="collapse(this);">제목 1</button>
    <div class="content">
        <p>내용 1 입니다.</p>
    </div>
    <button type="button" class="collapsible" onclick="collapse(this);">제목 2</button>
    <div class="content">
        <p>내용 2 입니다.</p>
    </div>
    <button type="button" class="collapsible" onclick="collapse(this);">제목 3</button>
    <div class="content">
        <p>내용 3 입니다.</p>
    </div>
</body>
</html>

 

만들고 나서 찾아보니까 아코디언 메뉴 자체는 <details>, <summary> 태그와 자바스크립트를 이용해서 만든 것도 있고,

아예 자바스크립트 없이 html, css 만으로도 구현한 사례가 있었다. 시간이 되면 더 공부를 해봐야겠다.