【问题标题】:SvelteKit returns window.innerWidth as undefined on initial page loadSvelteKit 在初始页面加载时返回未定义的 window.innerWidth
【发布时间】:2023-01-16 04:28:48
【问题描述】:

我有两个独立的组件,一个用于移动设备,另一个用于桌面。一次只能显示一个组件,具体取决于用户浏览器窗口的宽度。这是我的浓缩版:

<script>
    let innerWidth
</script>

<svelte:window bind:innerWidth />

<p>
  Inner Width: {innerWidth}
</p>

{#if innerWidth > 800}
    Desktop Content
{:else}
    Mobile Content
{/if}

我注意到当我加载页面时,{innerWidth} 迅速从 undefined 切换到适当的值。对于桌面用户来说,这是一个问题,因为在评估{#if innerWidth &gt; 800}时,Svelte 有innerWidth = undefined,所以显示的是 Mobile 内容。

有趣的是,只有当我直接加载页面时才会出现这个问题。如果我在 /subpage 上有这个功能,如果我访问 /index 然后访问 /subpage,预期的功能就会起作用。

有没有办法在初始页面加载时返回适当的值而不识别undefined?我想避免使用 CSS 媒体查询,但这是最后的手段。

【问题讨论】:

    标签: svelte sveltekit


    【解决方案1】:

    有没有办法在初始页面加载时返回适当的值而不识别undefined

    不使用默认配置,因为 SvelteKit 在第一页加载时使用服务器端渲染。无法在服务器上获取该信息。

    如果你想防止显示错误的内容,你也可以将你的内容包装在一个额外的#if中。

    {#if innerWidth != null}
        {#if innerWidth > 800}
            Desktop Content
        {:else}
            Mobile Content
        {/if}
    {/if}
    

    【讨论】:

      【解决方案2】:

      我认为这是一个 DOM 事件排序问题。 innerWidth 首次尝试访问时可能尚不可用。浏览器在完成完整的 CSS 布局之前没有它。

      如果您先导航/index,然后导航/subpage,则已经在innerWidth 中加载了一个值,因为已显示首页,尽管在重新布局发生之前,该值在导航期间可能是错误的。

      您不太可能在页面加载时获得正确的值,因为 Web 浏览器就是这样工作的。

      【讨论】:

        【解决方案3】:

        您收到错误是因为您试图访问服务器中的 window 元素(您的服务器不是浏览器)您需要一种方法来让服务器完成按下请求,以便当它到达客户端时,您可以检索您想要的数据,在此可以使用 svelte 浏览器对象来检查您是在服务器上还是在客户端上。

        <script>
            import { browser } from '$app/env';
        
            let innerWidth // you can also set your default width
        
            if (browser){
                innerWidth = window.innerWidth;
            }
        </script>
        
        
        {#if innerWidth > 800}
           <DesktopContent />
        {:else}
           <MobileContent />
        {/if}
        

        如果你想在调整大小时缩放,你可以使用它来代替

        <script>
            import { browser } from '$app/env';
        
            let innerWidth // you can also set your default width
        
            const updateWindowSize = () =>{
                innerWidth = window.innerWidth;
            }
            if (browser){
                updateWindowSize() // to set the initial window size
                window.onresize = updateWindowSize; // run when ever the window size change
                
            }
        </script>
        

        【讨论】:

          【解决方案4】:

          我有一个非常相似的设置,我刚刚在本地的 sveltekit 中尝试过并且它有效。我有一个 Nav 组件,它控制您是否具有用于较宽屏幕的水平导航 (Hnav) 或用于较小屏幕的垂直导航 (Vnav)。

          导航苗条

          <script>
              import Vnav from './Vnav.svelte';
              import Hnav from './Hnav.svelte';
              let screenWidth;
              $: if (screenWidth > 800) {
                   <!-- close sidebar -->
              }
           </script>
          
           <svelte:window bind:innerWidth={screenWidth} />
          
           {#if screenWidth > 800}
             <Hnav />
           {:else}
              <!-- open sidebar -->
              <Vnav />
           {/if}
          

          【讨论】:

            猜你喜欢
            • 2022-01-06
            • 1970-01-01
            • 1970-01-01
            • 2020-07-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-25
            • 1970-01-01
            相关资源
            最近更新 更多