Solution 1 :

While hiding the element, you are also hiding the clicked element if it was open. And later on you are toggling it, this cancels the effect and results in no change. You have to put a check to not hide the current one.

Like this

const btns = document.querySelectorAll(".accordionBtn");
const acc_contents = document.querySelectorAll(".accordionContent");

btns.forEach((btn) => {
    btn.addEventListener("click", (e) => {
        acc_contents.forEach((acc) => {
            if (acc.classList.contains("show") && acc !== e.target.nextElementSibling) {
                acc.classList.remove("show");
            }
        });

        const sibling = btn.nextElementSibling;
        if (sibling) {
            sibling.classList.toggle("show");
        }
    });
});

Problem :

I wrote this simple html and here is the full pen.

<div class="center">
    <div class="menu">
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-user"></i> Profile</button>
            <div class="accordionContent">
                <a href="#">Posts</a>
                <a href="#">Pictures</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="far fa-envelope"></i> Message</button>
            <div class="accordionContent">
                <a href="#">New</a>
                <a href="#">Sent</a>
                <a href="#">Spam</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-cog"></i> Settings</button>
            <div class="accordionContent">
                <a href="#">Password</a>
                <a href="#">Language</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-sign-out-alt"></i> Sign out</button>
        </div>
    </div>
</div>

and JavaScript to toggle respective accordion content:

const btns = document.querySelectorAll(".accordionBtn");

    btns.forEach((btn) => {
        btn.addEventListener("click", () => {
           
            const sibling = btn.nextElementSibling;
            if (sibling) {
                sibling.classList.toggle("show");
            }
        });
    });

but when I click on one accordion I want others to collapse, here is my solution:

const btns = document.querySelectorAll(".accordionBtn");
const acc_contents = document.querySelectorAll(".accordionContent");

btns.forEach((btn) => {
    btn.addEventListener("click", () => {
        // new
        acc_contents.forEach(acc => {
            if(acc.classList.contains('show')) {
                acc.classList.remove('show');
            }
        })
        
        const sibling = btn.nextElementSibling;
        if (sibling) {
            sibling.classList.toggle("show");
        }
    });
});

but the problem is it disables toggle functionality. Can anyone help?

By

Leave a Reply

Your email address will not be published. Required fields are marked *