使用本地存储保存折叠菜单的状态和所选菜单的颜色



嘿,伙计们,我有一个侧菜单栏,它在按下切换图标时打开和关闭,但当页面刷新时(或按下另一个菜单时(菜单栏会折叠,所选菜单的颜色也会消失。我知道本地存储是保持状态的好方法。我试了很多次,但都想不出一个方法。非常感谢您的帮助。下面是我的工作代码,到目前为止没有本地存储。谢谢你抽出时间。

/*===== EXPANDER MENU  =====*/
const showMenu = (toggleId, navbarId, bodyId) => {
const toggle = document.getElementById(toggleId),
navbar = document.getElementById(navbarId),
bodypadding = document.getElementById(bodyId)
if (toggle && navbar) {
toggle.addEventListener('click', () => {
navbar.classList.toggle('expander')
bodypadding.classList.toggle('body-pd')
})
}
}
showMenu('nav-toggle', 'navbar', 'body-pd')
/*===== LINK ACTIVE  =====*/
const linkColor = document.querySelectorAll('.nav__link')
function colorLink() {
linkColor.forEach(l => l.classList.remove('active'))
this.classList.add('active')
}
linkColor.forEach(l => l.addEventListener('click', colorLink))

/*===== COLLAPSE MENU  =====*/
const linkCollapse = document.getElementsByClassName('collapse__link')
var i
for (i = 0; i < linkCollapse.length; i++) {
linkCollapse[i].addEventListener('click', function() {
const collapseMenu = this.nextElementSibling
collapseMenu.classList.toggle('showCollapse')
const rotate = collapseMenu.previousElementSibling
rotate.classList.toggle('rotate')
})
}
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap");
/*===== VARIABLES CSS =====*/
:root {
--nav-width: 92px;
/*===== Colores =====*/
--first-color: #016FFE;
--bg-color: #1C1F2B;
--sub-color: #B6CEFC;
--white-color: #FFF;
/*===== Fuente y tipografia =====*/
--body-font: 'Poppins', sans-serif;
--normal-font-size: 1rem;
--small-font-size: .875rem;
/*===== z index =====*/
--z-fixed: 100;
}

/*===== BASE =====*/
*,
::before,
::after {
box-sizing: border-box;
}
body {
position: relative;
margin: 0;
padding: 2rem 0 0 6.75rem;
font-family: var(--body-font);
font-size: var(--normal-font-size);
transition: .5s;
}
h1 {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
a {
text-decoration: none;
}

/*===== l NAV =====*/
.l-navbar {
position: fixed;
top: 0;
left: 0;
width: var(--nav-width);
height: 100vh;
background-color: var(--bg-color);
color: var(--white-color);
padding: 1.5rem 1.5rem 2rem;
transition: .5s;
z-index: var(--z-fixed);
}

/*===== NAV =====*/
.nav {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.nav__brand {
display: grid;
grid-template-columns: max-content max-content;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.nav__toggle {
font-size: 1.25rem;
padding: .75rem;
cursor: pointer;
}
.nav__logo {
color: var(--white-color);
font-weight: 600;
}
.nav__link {
display: grid;
grid-template-columns: max-content max-content;
align-items: center;
column-gap: .75rem;
padding: .75rem;
color: var(--white-color);
border-radius: .5rem;
margin-bottom: 1rem;
transition: .3s;
cursor: pointer;
transition: 0.5s;
}
.nav__link:hover {
background-color: var(--first-color);
}
.nav__icon {
font-size: 1.25rem;
}
.nav__name {
font-size: var(--small-font-size);
}

/*Expander menu*/
.expander {
width: calc(var(--nav-width) + 9.25rem);
}

/*Add padding body*/
.body-pd {
padding: 2rem 0 0 16rem;
}

/*Active links menu*/
.active {
background-color: var(--first-color);
}

/*===== COLLAPSE =====*/
.collapse {
grid-template-columns: 20px max-content 1fr;
}
.collapse__link {
justify-self: flex-end;
transition: .5s;
}
.collapse__menu {
display: none;
padding: .75rem 2.25rem;
}
.collapse__sublink {
color: var(--sub-color);
font-size: var(--small-font-size);
}
.collapse__sublink:hover {
color: var(--white-color);
}

/*Show collapse*/
.showCollapse {
display: block;
}

/*Rotate icon*/
.rotate {
transform: rotate(180deg);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ===== CSS ===== -->
<link rel="stylesheet" href="assets/css/styles.css">
<link href="https://fonts.googleapis.com/css?family=Comfortaa&display=swap" rel="stylesheet">
<title>Sidebar sub menus</title>
</head>

<body id="body-pd">

<div class="l-navbar" id="navbar">
<nav class="nav">
<div>
<div class="nav__brand">
<ion-icon name="menu-outline" class="nav__toggle" id="nav-toggle"></ion-icon>

</div>
<div class="nav__list">
<a href="template.html" class="nav__link active">
<ion-icon name="home-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Dashboard</span>
</a>
<a href="trial5.html" class="nav__link">
<ion-icon name="bulb-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Trailer Lights</span>
</a>
<div class="nav__link collapse">
<ion-icon name="videocam" class="nav__icon"></ion-icon>
<span class="nav__name">Video Feed</span>
<ion-icon name="chevron-down-outline" class="collapse__link"></ion-icon>
<ul class="collapse__menu">
<a href="#" class="collapse__sublink">Data</a>
<a href="#" class="collapse__sublink">Group</a>
<a href="#" class="collapse__sublink">Members</a>
</ul>
</div>
<a href="#" class="nav__link">
<ion-icon name="pie-chart-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Analytics</span>
</a>
<div class="nav__link collapse">
<ion-icon name="people-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Team</span>
<ion-icon name="chevron-down-outline" class="collapse__link"></ion-icon>
<ul class="collapse__menu">
<a href="#" class="collapse__sublink">Data</a>
<a href="#" class="collapse__sublink">Group</a>
<a href="#" class="collapse__sublink">Members</a>
</ul>
</div>
</div>
</div>
<a href="#" class="nav__link">
<ion-icon name="log-out-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Log Out</span>

</a>
</nav>
</div>

<!-- ===== IONICONS ===== -->
<script src="https://unpkg.com/ionicons@5.1.2/dist/ionicons.js"></script>
<!-- ===== MAIN JS ===== -->
<script src="assets/js/main.js"></script>


</body>

</html>

在添加事件侦听器的forEach循环中,我添加了一个数据属性来存储一个"索引";对于每个CCD_ 2。这就是单击时要存储在localStorage中的内容。

在同一循环中;index'存储,添加active类并删除其他所有位置。

我还修复了关于ioniconDeprecated script警告。;(

/*===== EXPANDER MENU  =====*/
const showMenu = (toggleId, navbarId, bodyId) => {
const toggle = document.getElementById(toggleId),
navbar = document.getElementById(navbarId),
bodypadding = document.getElementById(bodyId)
if (toggle && navbar) {
toggle.addEventListener('click', () => {
navbar.classList.toggle('expander')
bodypadding.classList.toggle('body-pd')
})
}
}
showMenu('nav-toggle', 'navbar', 'body-pd')
/*===== LINK ACTIVE  =====*/
const linkColor = document.querySelectorAll('.nav__link')
function colorLink() {
linkColor.forEach(l => l.classList.remove('active'))
this.classList.add('active')

// Added this to read data attribute
let this_index = this.getAttribute("data-nav_link_index")
//localStorage.setItem("active_nav_link", this_index) // Commeneted here because SO disallow it and throws errors
}
linkColor.forEach((l,i) => {
l.addEventListener('click', colorLink);

// Added this to set data attribute
l.setAttribute("data-nav_link_index", i);

// Added this to add the active class
// Commeneted here because SO disallow it and throws errors
/*
if(localStorage.getItem("active_nav_link")==i){
l.classList.add("active");
}else if(localStorage.getItem("active_nav_link")!==null){
l.classList.remove("active");
}
*/
})

/*===== COLLAPSE MENU  =====*/
const linkCollapse = document.getElementsByClassName('collapse__link')
var i
for (i = 0; i < linkCollapse.length; i++) {
linkCollapse[i].addEventListener('click', function() {
const collapseMenu = this.nextElementSibling
collapseMenu.classList.toggle('showCollapse')
const rotate = collapseMenu.previousElementSibling
rotate.classList.toggle('rotate')
})
}
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap");
/*===== VARIABLES CSS =====*/
:root {
--nav-width: 92px;
/*===== Colores =====*/
--first-color: #016FFE;
--bg-color: #1C1F2B;
--sub-color: #B6CEFC;
--white-color: #FFF;
/*===== Fuente y tipografia =====*/
--body-font: 'Poppins', sans-serif;
--normal-font-size: 1rem;
--small-font-size: .875rem;
/*===== z index =====*/
--z-fixed: 100;
}

/*===== BASE =====*/
*,
::before,
::after {
box-sizing: border-box;
}
body {
position: relative;
margin: 0;
padding: 2rem 0 0 6.75rem;
font-family: var(--body-font);
font-size: var(--normal-font-size);
transition: .5s;
}
h1 {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
a {
text-decoration: none;
}

/*===== l NAV =====*/
.l-navbar {
position: fixed;
top: 0;
left: 0;
width: var(--nav-width);
height: 100vh;
background-color: var(--bg-color);
color: var(--white-color);
padding: 1.5rem 1.5rem 2rem;
transition: .5s;
z-index: var(--z-fixed);
}

/*===== NAV =====*/
.nav {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
}
.nav__brand {
display: grid;
grid-template-columns: max-content max-content;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.nav__toggle {
font-size: 1.25rem;
padding: .75rem;
cursor: pointer;
}
.nav__logo {
color: var(--white-color);
font-weight: 600;
}
.nav__link {
display: grid;
grid-template-columns: max-content max-content;
align-items: center;
column-gap: .75rem;
padding: .75rem;
color: var(--white-color);
border-radius: .5rem;
margin-bottom: 1rem;
transition: .3s;
cursor: pointer;
transition: 0.5s;
}
.nav__link:hover {
background-color: var(--first-color);
}
.nav__icon {
font-size: 1.25rem;
}
.nav__name {
font-size: var(--small-font-size);
}

/*Expander menu*/
.expander {
width: calc(var(--nav-width) + 9.25rem);
}

/*Add padding body*/
.body-pd {
padding: 2rem 0 0 16rem;
}

/*Active links menu*/
.active {
background-color: var(--first-color);
}

/*===== COLLAPSE =====*/
.collapse {
grid-template-columns: 20px max-content 1fr;
}
.collapse__link {
justify-self: flex-end;
transition: .5s;
}
.collapse__menu {
display: none;
padding: .75rem 2.25rem;
}
.collapse__sublink {
color: var(--sub-color);
font-size: var(--small-font-size);
}
.collapse__sublink:hover {
color: var(--white-color);
}

/*Show collapse*/
.showCollapse {
display: block;
}

/*Rotate icon*/
.rotate {
transform: rotate(180deg);
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ===== CSS ===== -->
<link rel="stylesheet" href="assets/css/styles.css">
<link href="https://fonts.googleapis.com/css?family=Comfortaa&display=swap" rel="stylesheet">
<title>Sidebar sub menus</title>
</head>

<body id="body-pd">

<div class="l-navbar" id="navbar">
<nav class="nav">
<div>
<div class="nav__brand">
<ion-icon name="menu-outline" class="nav__toggle" id="nav-toggle"></ion-icon>

</div>
<div class="nav__list">
<a href="template.html" class="nav__link active">
<ion-icon name="home-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Dashboard</span>
</a>
<a href="trial5.html" class="nav__link">
<ion-icon name="bulb-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Trailer Lights</span>
</a>
<div class="nav__link collapse">
<ion-icon name="videocam" class="nav__icon"></ion-icon>
<span class="nav__name">Video Feed</span>
<ion-icon name="chevron-down-outline" class="collapse__link"></ion-icon>
<ul class="collapse__menu">
<a href="#" class="collapse__sublink">Data</a>
<a href="#" class="collapse__sublink">Group</a>
<a href="#" class="collapse__sublink">Members</a>
</ul>
</div>
<a href="#" class="nav__link">
<ion-icon name="pie-chart-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Analytics</span>
</a>
<div class="nav__link collapse">
<ion-icon name="people-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Team</span>
<ion-icon name="chevron-down-outline" class="collapse__link"></ion-icon>
<ul class="collapse__menu">
<a href="#" class="collapse__sublink">Data</a>
<a href="#" class="collapse__sublink">Group</a>
<a href="#" class="collapse__sublink">Members</a>
</ul>
</div>
</div>
</div>
<a href="#" class="nav__link">
<ion-icon name="log-out-outline" class="nav__icon"></ion-icon>
<span class="nav__name">Log Out</span>

</a>
</nav>
</div>

<!-- ===== IONICONS ===== -->
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<!-- ===== MAIN JS ===== -->
<script src="assets/js/main.js"></script>


</body>

</html>

SO代码段中不允许使用localStorage。。。请查看我的CodePen


编辑

关于菜单的展开/折叠状态,您只需要存储另一个项目。。。

/*===== EXPANDER MENU  =====*/
// Have the menu state in a variable
let menu_expanded = Boolean(localStorage.getItem("expanded"));
const showMenu = (toggleId, navbarId, bodyId) => {
const toggle = document.getElementById(toggleId),
navbar = document.getElementById(navbarId),
bodypadding = document.getElementById(bodyId)

if (toggle && navbar) {
toggle.addEventListener('click', () => {

// Toggle the variable
menu_expanded = !menu_expanded

// Use the variable in both toggle method
navbar.classList.toggle('expander', menu_expanded)
bodypadding.classList.toggle('body-pd', menu_expanded)

// Save to localStorage
localStorage.setItem("expanded", (menu_expanded)?"true":"false")
})
}
}
showMenu('nav-toggle', 'navbar', 'body-pd')

最新更新