在我的 SvelteKit 项目中,我有一个布局,应该水平显示所有彼此相邻的页面,但它们都是
100vw
宽,因此一次只有一个显示在屏幕“内”(其他页面位于屏幕的左/右),并且当从一个页面导航到另一页面时,它们都应该很好地向侧面滑动,以便您导航到的页面显示在屏幕的中心。 这里是 Svelte 项目中的一个快速演示,展示了我希望它如何工作。
但是,我想在SvelteKit项目中实现这一点,我无法提前加载所有页面的内容。相反,当前页面内容是使用
<slot />
文件中的 +layout.svelte
加载的,而我对其他页面的解决方法是显示一些虚拟文本。 这里是另一个 Svelte 项目中的快速演示,反映了这一点。
这已经足够好了,但是如果当前页面在离开当前页面时保留其内容,而不是立即将其内容更改为虚拟文本,那就太好了。
我的问题是:我能以某种方式将
<slot />
加载的旧内容保留几秒钟然后消失吗?
这是我的
+layout.svelte
文件中的 SvelteKit 代码当前的样子:
<div class="pages" style:--shownPageIndex={shownPageIndex}>
{#each mainPages as mainPage, pageIndex (mainPage.name)}
<div class="page" style:--pageIndex={pageIndex}>
{#if isUrlLeadingToMainPage($page.url.pathname, mainPage)}
<h1>{mainPage.name}</h1>
<!--
The problem is here. When going to another page, the condition
in this #if becomes false, so the <slot /> below is immediately
removed, and the :else-part is shown instead. I want to delay this
for 1 second. But for the page I'm coming to, the change should
happen immediately.
-->
<slot />
{:else}
<div class="fakedPageContent">
<h1>{mainPage.name}</h1>
<p>This is the faked content...</p>
</div>
{/if}
</div>
{/each}
</div>
您可以尝试复制导航上的页面内容,例如使用路由
/paging/[page]
将页面索引存储在参数中:
import { onNavigate } from '$app/navigation';
import { page } from '$app/stores';
let pageContents = [];
let viewport;
onNavigate(e => {
const route = '/paging/[page]';
if (e.from.route.id != route || e.to.route.id != route)
return;
const from = +e.from.params.page;
const page = viewport.querySelector(`[data-index="${from}"]`);
pageContents[from] = [...page.cloneNode(true).childNodes];
});
function insert(node, children) {
node.append(...children.map(child => child.cloneNode(true)));
}
<div class="viewport" bind:this={viewport}>
{#each pages as page, i}
<div class="page" data-index={i}>
{#if i == $page.params.page}
<slot />
{:else}
{#if i in pageContents}
<div use:insert={pageContents[i]}></div>
{:else}
<div>...</div> <!-- not loaded before -->
{/if}
{/if}
</div>
{/each}
</div>