classlist.toggle() with force false still adding class

I have a side navigation bar with a button to toggle showing just the icons or to show the icons and the text. There are multiple different HTML pages that share this nav bar, so I needed to save the nav bar’s state for when you switch to each (Dashboard to Items, Contacts to Dashboard, etc). I do this using the follow code:

var navBar = document.querySelector(".side-bar");
var toggle = document.querySelector(".nav-toggle");

window.onload = () =>
{
    let isClosed = localStorage.getItem("navState");
    navBar.classList.toggle("nav-is-closed", isClosed);
}

toggle.addEventListener("click", () =>
{
    let isClosed = navBar.classList.toggle("nav-is-closed");
    localStorage.setItem("navState", isClosed);
});
.side-bar {
  position: relative;
  background-color: var(--default-back-color);
  min-width: 200px;
}

.nav-is-closed {
  min-width: inherit;
}

.nav-is-closed a h2 {
  display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="resources/css/styles.css">

    <!--Google Fonts-->
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Neucha&family=Poppins:wght@300&display=swap" rel="stylesheet">

    <title>Rucksack</title>
</head>
<body>
    <header>
        <div>
            <a href="#"><img src="resources/images/rucksack.png" alt=""></a>
            <h1 class="title">Rucksack</h1>
        </div>
        <div>
            <a class="smaller-icon" href="#"><img src="resources/images/gear.png" alt=""></a>
            <a href="#"><img src="resources/images/blue-profile.png" alt=""></a>
        </div>
    </header>
    <main>
        <section id="main-section">
            <nav class="side-bar">
                <a class="selected-nav" href="dashboard"><img src="resources/images/house-icon.png" alt=""><h2>Dashboard</h2></a>
                <a href="items"><img src="resources/images/item-icon.png" alt=""><h2>Items</h2></a>
                <hr class="nav-break">
                <a href="contacts"><img src="resources/images/contacts-icon.png" alt=""><h2>Contacts</h2></a>
                <hr class="nav-break">
                <a href="reports"><img src="resources/images/reports-icon.png" alt=""><h2>Reports</h2></a>

                <div class="nav-toggle"><img src="resources/images/arrow-icon.png" alt=""></div>
            </nav>
            <div class="content">
                <strong>Content</strong>
            </div>
        </section>
    </main>
    <script src="shell-controls.js"></script>
</body>
</html>

Everything works fine, except when you move to a new page while the nav is open. It closes even though in window.onload, isClosed is false. As far as I know, toggle with force set to false removes the class, but in this case it’s still adding it.

Open
Close

3 thoughts on “classlist.toggle() with force false still adding class”

  1. As Kaiido said, isClosed was being pulled from localStorage as a string, which caused toggleClass to think the string of "false" was truthy, therefore still adding the ‘nav-is-closed’ class. Adding JSON.parse when getting isClosed and adding JSON.stringify when setting isClosed in localStorage solves the problem.

    Reply

Leave a Comment