You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SvelteKit中<svelte:head>内JS文件仅首次加载,刷新后失效

解决SvelteKit中Static目录JS文件仅首次加载生效的问题

原因分析

  • SvelteKit采用客户端路由导航时,页面不会完全刷新,DOMContentLoaded事件仅在首次页面加载时触发一次,后续路由切换、页面刷新都不会重新触发该事件。
  • 浏览器会缓存已加载的JS文件,重复添加相同src的<script>标签时,不会重新执行脚本,也不会触发on:load事件。

具体解决方案

方案1:抽离脚本逻辑为可调用函数,在组件生命周期触发

修改/static/js/script.js,将DOMContentLoaded内的逻辑抽成独立函数:

// /static/js/script.js
window.initScript = function() {
  // 原DOMContentLoaded中的业务逻辑写在这里
  console.log('脚本初始化完成');
};

// 保留首次加载的触发逻辑,兼容直接访问页面的场景
document.addEventListener("DOMContentLoaded", window.initScript);

在布局组件中利用onMount钩子,每次组件挂载时调用该函数:

<script>
  import { onMount } from 'svelte';

  onMount(() => {
    // 确保脚本已加载后调用初始化函数
    if (window.initScript) {
      window.initScript();
    }
  });
</script>

<svelte:head>
  <link rel="stylesheet" href="/css/style.css" />
  <script src="/js/script.js"></script>
</svelte:head>

<slot />

方案2:通过app.html注入脚本,监听路由变化重新执行

在src/app.html的<body>末尾添加脚本,监听SvelteKit的路由结束事件:

<!-- src/app.html -->
<body>
  %sveltekit.body%
  <script src="/js/script.js"></script>
  <script>
    // 每次路由切换完成后重新执行脚本逻辑
    window.addEventListener('sveltekit:navigation-end', () => {
      if (window.initScript) {
        window.initScript();
      }
    });
  </script>
</body>

对应的script.js需将初始化逻辑挂载到window对象上(同方案1中的脚本修改方式)。

方案3:强制特定路由完全刷新(仅适用于特殊场景)

如果某个页面必须完全刷新才能正常工作,可在路由组件中添加配置:

<script>
  // 强制该路由使用服务端渲染且禁用客户端导航
  export const ssr = true;
  export const csr = false;
</script>

<!-- 页面内容 -->

关于on:load事件不触发的说明

浏览器加载过的JS文件会被缓存,重复添加相同src的<script>标签时,不会重新发起请求,自然也不会触发on:load事件。若需验证脚本加载状态,可直接在脚本内部添加console.log输出,或通过DOM查询确认脚本标签是否存在。

内容的提问来源于stack exchange,提问作者user3291025

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:36:16