本文解决动态通过 fetch 加载 html 片段(如导航栏)后,javascript 事件监听器失效的问题——核心原因是原脚本仅在初始页面执行,未对动态插入的 dom 重新绑定事件。
本文解决动态通过 fetch 加载 html 片段(如导航栏)后,javascript 事件监听器失效的问题——核心原因是原脚本仅在初始页面执行,未对动态插入的 dom 重新绑定事件。
在多页网站中复用导航栏时,直接 fetch('index.html') 并注入 HTML 是常见做法,但这种方式存在一个关键陷阱:动态插入的 DOM 元素不会自动继承原始页面中已执行的 JavaScript 逻辑。你当前的 script.js 在 index.html 中运行并绑定了 .hamburger 和 .nav-link 的事件监听器;而 home.html 等子页面只引入了空 <script id="replace_with_navbar"> 占位符,并未重新执行这些初始化逻辑——导致即使导航栏 HTML 成功渲染,汉堡菜单点击无响应。
将事件绑定逻辑从 script.js 中抽离或内联到 nav.js 的 fetch 回调中,确保每次 navbar 被注入后,相关 DOM 元素已存在且监听器被正确挂载:
// nav.js(推荐:所有逻辑集中于此)fetch('index.html') .then(res => { if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); return res.text(); }) .then(text => { // 解析 index.html,提取 navbar 部分(更健壮的做法) const parser = new DOMParser(); const doc = parser.parseFromString(text, 'text/html'); const navbar = doc.querySelector('.navbar'); // 精准定位,避免整个 body 被注入 if (!navbar) { throw new Error('Navbar element (.navbar) not found in index.html'); } // 替换占位符节点 const placeholder = document.querySelector('script#replace_with_navbar'); if (!placeholder) { throw new Error('Placeholder script#replace_with_navbar not found'); } const container = document.createElement('div'); container.appendChild(navbar.cloneNode(true)); // 深拷贝,避免引用问题 placeholder.parentNode.replaceChild(container, placeholder); // ✅ 关键:在此处重新绑定交互逻辑(与原 script.js 一致) const hamburger = document.querySelector('.hamburger'); const navMenu = document.querySelector('.nav-menu'); if (hamburger && navMenu) { hamburger.addEventListener('click', () => { hamburger.classList.toggle('active'); navMenu.classList.toggle('active'); }); document.querySelectorAll('.nav-link').forEach(link => { link.addEventListener('click', () => { hamburger.classList.remove('active'); navMenu.classList.remove('active'); }); }); } else { console.warn('Hamburger or nav-menu not found — mobile menu may not work.'); } }) .catch(err => { console.error('Failed to load navbar:', err); // 可选:降级显示静态提示或备用导航 });
通过将交互初始化逻辑与 DOM 插入逻辑严格耦合在同一个异步回调中,即可彻底解决“导航栏可见但不可交互”的问题——这是动态内容注入场景下的通用最佳实践。