sveltekit 路线更改时如何关闭下拉菜单?
How can I close my dropdown menu when sveltekit route changes?
我有一个 <SideBar />
组件,onDestroy()
似乎不会在路由更改时触发。
我需要在路线改变时关闭菜单,否则菜单会保持打开状态,这是一个糟糕的用户体验。
<script>
import { page } from '$app/stores';
import { onDestroy } from 'svelte';
let isMainNavOpen = true;
let isGroupNavOpen = false;
function toggleGroupMenu(e) {
e.preventDefault();
isGroupNavOpen = !isGroupNavOpen;
}
$: currentPath = $page.url.pathname;
</script>
<nav>
<header class="groups" class:closed={!isGroupNavOpen}>
<div class="dropdown">
<a href="#" class="toggler" on:click|preventDefault={toggleGroupMenu}>
<img src="/icons/chevron.svg" alt="" border="0" />
</a>
<ul>
{#each groupMenu as item, i}
<li class:active={currentPath === item.path}>
<a href="/groups/{item.id}"
><img
class="avatar"
src="/icons/avatar.group.png"
alt=""
border="0"
/>{item.name}</a
>
</li>
{/each}
</ul>
<a href="/groups" class="button secondary outlined">Explore Groups</a>
</div>
</header>
</nav>
<style>
nav {
padding: 1.2rem;
flex-grow: 1;
display: flex;
flex-direction: column;
}
nav header {
color: #fff;
display: flex;
flex-direction: column;
}
.groups.closed li:not(:first-child) {
display: none;
}
.groups .toggler {
position: absolute;
top: 2.5rem;
right: 1rem;
margin-left: 1.4rem;
}
.groups .toggler img {
transform: rotate(180deg);
}
.groups.closed .toggler img {
transform: rotate(0deg);
}
.groups ul {
width: 100%;
max-height: 22rem;
overflow-y: auto;
background-color: #060536;
color: #fff;
border-radius: 0.8rem;
}
.groups ul .active {
background-color: #34326d;
}
.groups .dropdown {
width: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
background-color: #060536;
}
header.groups {
padding: 0;
position: relative;
overflow: visible;
}
.groups .avatar {
width: 5rem;
display: block;
margin-right: 1.4rem;
}
.groups li {
display: flex;
justify-content: space-between;
align-items: center;
}
.groups li a {
padding: 1rem;
display: flex;
justify-content: flex-start;
align-items: center;
flex-grow: 1;
color: #fff;
text-decoration: none;
font-weight: 600;
word-break: break-all;
}
.groups .button {
font-weight: 600;
font-size: 1.4rem;
width: 80%;
margin: 1rem auto;
}
.groups.closed .button {
display: none;
}
nav ul {
display: flex;
flex-direction: column;
}
nav ul {
list-style-type: none;
padding: 0;
margin: 0;
flex: 1;
}
</style>
我可能还需要一个底衬,如果他们点击关闭菜单,它也会关闭。
我假设您将此边栏添加到布局页面的某处,这意味着在页面更改时此组件不会被破坏,它保持不变(除非您移动到具有不同布局的页面)。在 SvelteKit 中,导航仅更改 <slot>
中的部分,而不更改其余部分。
您可以通过简单地响应页面更改来解决此问题:
$: $page.url && (isGroupNavOpen = false)
我使用setTimeout来切换菜单内容的style display property,点击后关闭菜单内容:
<script>
...
let display = ""; // Svelte style property
...
</script>
<div class="nav-menu">
<div class:active class="menu-btn">
<span>{text}</span>
<i class="fa fa-caret-down" />
</div>
<div
class="menu-content"
style:display
on:click={() => {
display = "none";
setTimeout(() => (display = ""), 0);
}}>
<slot />
</div>
</div>
更新:
删除了 on:click
.
中的 stopPropagation
Sveltekit filesystem-based 路由器需要点击一下!
在响应式语句中使用 svelte-kit 中的“导航”商店
$: if($navigating) //代码;
我有一个 <SideBar />
组件,onDestroy()
似乎不会在路由更改时触发。
我需要在路线改变时关闭菜单,否则菜单会保持打开状态,这是一个糟糕的用户体验。
<script>
import { page } from '$app/stores';
import { onDestroy } from 'svelte';
let isMainNavOpen = true;
let isGroupNavOpen = false;
function toggleGroupMenu(e) {
e.preventDefault();
isGroupNavOpen = !isGroupNavOpen;
}
$: currentPath = $page.url.pathname;
</script>
<nav>
<header class="groups" class:closed={!isGroupNavOpen}>
<div class="dropdown">
<a href="#" class="toggler" on:click|preventDefault={toggleGroupMenu}>
<img src="/icons/chevron.svg" alt="" border="0" />
</a>
<ul>
{#each groupMenu as item, i}
<li class:active={currentPath === item.path}>
<a href="/groups/{item.id}"
><img
class="avatar"
src="/icons/avatar.group.png"
alt=""
border="0"
/>{item.name}</a
>
</li>
{/each}
</ul>
<a href="/groups" class="button secondary outlined">Explore Groups</a>
</div>
</header>
</nav>
<style>
nav {
padding: 1.2rem;
flex-grow: 1;
display: flex;
flex-direction: column;
}
nav header {
color: #fff;
display: flex;
flex-direction: column;
}
.groups.closed li:not(:first-child) {
display: none;
}
.groups .toggler {
position: absolute;
top: 2.5rem;
right: 1rem;
margin-left: 1.4rem;
}
.groups .toggler img {
transform: rotate(180deg);
}
.groups.closed .toggler img {
transform: rotate(0deg);
}
.groups ul {
width: 100%;
max-height: 22rem;
overflow-y: auto;
background-color: #060536;
color: #fff;
border-radius: 0.8rem;
}
.groups ul .active {
background-color: #34326d;
}
.groups .dropdown {
width: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
background-color: #060536;
}
header.groups {
padding: 0;
position: relative;
overflow: visible;
}
.groups .avatar {
width: 5rem;
display: block;
margin-right: 1.4rem;
}
.groups li {
display: flex;
justify-content: space-between;
align-items: center;
}
.groups li a {
padding: 1rem;
display: flex;
justify-content: flex-start;
align-items: center;
flex-grow: 1;
color: #fff;
text-decoration: none;
font-weight: 600;
word-break: break-all;
}
.groups .button {
font-weight: 600;
font-size: 1.4rem;
width: 80%;
margin: 1rem auto;
}
.groups.closed .button {
display: none;
}
nav ul {
display: flex;
flex-direction: column;
}
nav ul {
list-style-type: none;
padding: 0;
margin: 0;
flex: 1;
}
</style>
我可能还需要一个底衬,如果他们点击关闭菜单,它也会关闭。
我假设您将此边栏添加到布局页面的某处,这意味着在页面更改时此组件不会被破坏,它保持不变(除非您移动到具有不同布局的页面)。在 SvelteKit 中,导航仅更改 <slot>
中的部分,而不更改其余部分。
您可以通过简单地响应页面更改来解决此问题:
$: $page.url && (isGroupNavOpen = false)
我使用setTimeout来切换菜单内容的style display property,点击后关闭菜单内容:
<script>
...
let display = ""; // Svelte style property
...
</script>
<div class="nav-menu">
<div class:active class="menu-btn">
<span>{text}</span>
<i class="fa fa-caret-down" />
</div>
<div
class="menu-content"
style:display
on:click={() => {
display = "none";
setTimeout(() => (display = ""), 0);
}}>
<slot />
</div>
</div>
更新:
删除了 on:click
.
中的 stopPropagation
Sveltekit filesystem-based 路由器需要点击一下!
在响应式语句中使用 svelte-kit 中的“导航”商店
$: if($navigating) //代码;