滚动到 svelte 的元素

问题描述 投票:0回答:1

我有一个

div
,我希望页面在安装时滚动到它。该 div 有一个 id,由 URL 搜索参数确定。

不知道为什么,当我调用 document.getElementById(

#${referProductId}
) 时,结果为 null。是因为条件渲染的原因吗? (注:referProductId存在)

在脚本标签内

let layout: "grid" | "list" = "grid"
let referProductId = ""

page?.subscribe(({ url }) => {
    // set layout value
    // ... similar code to below with .get("layout")

    const product_id = url.searchParams.get('product_id');
    if (product_id) {
        referProductId = product_id;
    }
});

$: if (browser && referProductId) {
    const product = document.getElementById(`#${referProductId}`);
    console.log(product); // this logs null
    if (product) {
        product.scrollIntoView({ behavior: 'smooth' });
    }

在简洁的标记内

<div
    class={cn(
        'w-full gap-4',
        displayType === 'grid' && 'grid grid-cols-2',
        displayType === 'list' && 'flex flex-col'
    )}
>
    {#await data.products}
        {#if displayType === 'grid'}
            <Skeleton class="aspect-square h-full w-full rounded-lg" />
            <Skeleton class="aspect-square h-full w-full rounded-lg" />
        {:else if displayType === 'list'}
            <div class="flex w-full flex-col gap-4">
                <Skeleton class="h-16 w-full rounded-lg" />
                <Skeleton class="h-16 w-full rounded-lg" />
            </div>
        {/if}
    {:then products}
        {#each products as product, i}
            {#if displayType === 'grid'}
                <div
                    id={String(product.id)}
                    in:fly={{
                        y: -40,
                        opacity: 0,
                        delay: i * 100,
                        duration: 250,
                        easing: cubicInOut
                    }}
                >
                    <component />
                </div>
            {:else if displayType === 'list'}
                <div
                    id={String(product.id)}
                    in:fly={{
                        y: -40,
                        opacity: 0,
                        delay: i * 100,
                        duration: 250,
                        easing: cubicInOut
                    }}
                >
                    <component />
                </div>
            {/if}
        {/each}
    {:catch error}
        <p>Error loading products</p>
    {/await}
svelte sveltekit
1个回答
0
投票

不建议在组件代码中使用手动订阅,如果不正确清理,可能会导致泄漏。为了聚焦,您可以以相反的方式处理它:通过动作从元素。

$: referProductId = getProductId($page.url); // implement get logic in function

function scrollIntoView(node, scroll)
{
  function update(scroll) {
    if (scroll)
      node.scrollIntoView({ behavior: 'smooth' });
  }

  update(scroll);
  return { update };
}
<!-- on product element -->
<div
  id={product.id}
  use:scrollIntoView={product.id == referProductId}
  ...
© www.soinside.com 2019 - 2024. All rights reserved.