解决 Astro View Transitions 导致的脚本挂载失效
Astro
Astro JavaScript Frontend 现象描述
在 Astro 项目中开启 View Transitions 后,搜索框会出现一种奇怪的 Bug:首页冷启动进入时搜索正常,但通过导航跳转到博客列表页或内页后,搜索框点击没有任何反应,监听器似乎没有挂载。
根因分析
这种问题出在脚本执行时机的理解偏差上。
通常开发者习惯使用 DOMContentLoaded 来初始化脚本。在传统的网页模型中,每次跳转都是整页刷新,这个事件会稳定触发。
但在开启 View Transitions 后,Astro 的页面跳转变成了基于 Ajax 的局部更新。浏览器并没有重新加载整页,只是替换了 Body 内容。这就导致 DOMContentLoaded 事件在后续的跳转中不再触发。结果就是新页面的 HTML 结构虽然出来了,但脚本里的 addEventListener 逻辑没有重跑,搜索框也就成了死组件。
修复方案
必须放弃标准的 DOMContentLoaded,改用 Astro 提供的专有生命周期事件。
1. 使用 astro:page-load
astro:page-load 会在页面初始加载以及每一次视图转换完成后触发。将初始化逻辑封装成函数,并绑定到这个事件上。
<script>
function initSearch() {
const form = document.getElementById('smartSearchForm');
if (!form) return;
form.addEventListener('submit', (event) => {
event.preventDefault();
// 执行搜索跳转逻辑
console.log("搜索逻辑已激活");
});
}
// 核心修复:确保每次页面转换后都重新绑定监听器
document.addEventListener('astro:page-load', initSearch);
</script>
- 脚本放置建议 如果搜索框是一个全局复用的组件,建议将该脚本直接放在组件内部。Astro 会自动处理脚本的打包。由于使用了事件监听,脚本在多次跳转中会保持正确挂载,不会出现逻辑断层。