Laravel+Inertia+Svelte环境下如何移除body中追加的<script>标签?
解决动态页面脚本冲突的方案
针对Laravel+Inertia+Svelte架构下,页面切换时旧脚本未移除导致的冲突问题,这里提供两种实用的实现方式:
方案一:全局导航监听 + 标识类清理
1. 全局监听页面导航事件
在应用入口文件(比如resources/js/app.js)中,监听Inertia的导航事件,每次跳转前清理所有标记过的页面专属脚本:
import { Inertia } from '@inertiajs/inertia'; // 导航开始时清理旧脚本 Inertia.on('navigate', () => { document.querySelectorAll('script.page-script').forEach(el => el.remove()); });
2. 封装脚本加载工具函数
创建通用函数,负责加载指定脚本并添加标识类:
// resources/js/utils/loadPageScript.js export async function loadPageScript(scriptUrl) { const script = document.createElement('script'); script.src = scriptUrl; script.classList.add('page-script'); script.type = 'text/javascript'; // 等待脚本加载完成 await new Promise((resolve, reject) => { script.onload = resolve; script.onerror = () => reject(new Error(`加载脚本失败:${scriptUrl}`)); document.body.appendChild(script); }); }
3. 页面组件中调用
在登录页、重置密码页的onMount钩子中加载对应脚本:
Login.svelte
<script> import { onMount } from 'svelte'; import { loadPageScript } from '../utils/loadPageScript'; onMount(async () => { await loadPageScript('/js/password-addon.init.js'); }); </script> <!-- 登录页内容 -->
ResetPassword.svelte
<script> import { onMount } from 'svelte'; import { loadPageScript } from '../utils/loadPageScript'; onMount(async () => { await loadPageScript('/js/password-create.init.js'); }); </script> <!-- 重置密码页内容 -->
方案二:Svelte Store 跟踪脚本状态
如果需要更精细的生命周期控制,用Svelte Store跟踪已加载脚本:
1. 创建脚本状态Store
// resources/js/stores/scriptStore.js import { writable } from 'svelte/store'; export const loadedScripts = writable([]);
2. 封装带自动清理的加载函数
// resources/js/utils/loadPageScript.js import { loadedScripts } from '../stores/scriptStore'; export async function loadPageScript(scriptUrl) { // 先移除所有已加载的旧脚本 $loadedScripts.forEach(script => script.remove()); loadedScripts.set([]); const script = document.createElement('script'); script.src = scriptUrl; script.type = 'text/javascript'; await new Promise((resolve, reject) => { script.onload = resolve; script.onerror = reject; document.body.appendChild(script); }); // 将新脚本加入跟踪列表 loadedScripts.update(list => [...list, script]); }
3. 页面组件中使用
和方案一一致,在组件onMount中调用加载函数即可,每次加载新脚本时会自动清理旧脚本。
额外提示
- 如果模板有页面专属CSS,可参照相同逻辑处理:创建
<link>标签并添加标识类,导航时移除旧标签再加载新的。 - 可根据业务需求为脚本加载失败添加错误提示或降级逻辑。
- 确保脚本路径正确,Laravel静态资源通常放在
public/js目录下,对应URL为/js/xxx.js。
内容的提问来源于stack exchange,提问作者user21932874
相关产品推荐
相关产品推荐

