
本文介绍一种无需服务端语言(如 php)或构建工具,仅使用原生 javascript 和 html 实现页眉/页脚复用的方法,适用于静态站点(.html 文件),解决多页面重复维护头部导航的痛点。
本文介绍一种无需服务端语言(如 php)或构建工具,仅使用原生 javascript 和 html 实现页眉/页脚复用的方法,适用于静态站点(.html 文件),解决多页面重复维护头部导航的痛点。
在开发多页面静态网站(如影院管理系统)时,保持页眉(header)和页脚(footer)的一致性至关重要。但 HTML 原生不支持文件内嵌(如 PHP 的 include 或 <template> 的声明式复用),而 <link rel="import"> 已被废弃,服务器端渲染又不符合 .html 静态部署需求。此时,基于 Fetch API 的客户端动态注入是最轻量、兼容性好且无需额外依赖的解决方案。
✅ 推荐实现方式:JavaScript 动态加载 HTML 片段
核心思路:将公共结构(如导航栏)抽离为独立的 header.html 文件,通过 JavaScript 在页面加载时异步获取其内容,并注入到指定容器中。
步骤一:创建可复用的 header.html(纯 HTML 片段)
注意:该文件不包含 <html>、<head> 或 <body> 标签,仅保留语义化结构:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
<!-- header.html -->
<nav class="navigation-open">
<div class="global container grid-x">
<div class="logowrapper grid-x">
<div class="logo-container">
<a href="index.html">
<img class="logo" src="../img/logo.png" alt="Cate Cinema Logo">
</a>
</div>
</div>
<div class="dashboard-nav cell grid-x">
<nav class="choicewrapper">
<ul class="wrapper">
<li class="page-cinema"><a href="#" class="gradient-fill-hover"><span>A</span><span>l</span><span> </span><span>C</span><span>i</span><span>n</span><span>e</span><span>m</span><span>a</span></a></li>
<li class="page-card"><a href="#" class="gradient-fill-hover"><span>C</span><span>a</span><span>r</span><span>d</span><span> </span><span>e</span><span> </span><span>P</span><span>r</span><span>o</span><span>m</span><span>o</span></a></li>
<li class="page-pass"><a href="#" class="gradient-fill-hover"><span>P</span><span>a</span><span>s</span><span>s</span></a></li>
</ul>
</nav>
</div>
<nav class="loginwrapper grid-x cell align-right">
<div class="form-search-s grid-x">
<form class="form-search" onsubmit="event.preventDefault();" role="search">
<label for="search">Search for stuff</label>
<input class="input-search" type="search" id="search" placeholder="Search..." autofocus required>
<button type="submit" class="btn-search">Go</button>
</form>
</div>
<div class="profile-login">
<a href="../login/login.html" title="Accedi / Registrati">
<i class="fas fa-user"></i>
<span>Login</span>
<i class="fas fa-caret-down"></i>
</a>
<!-- 下拉菜单逻辑建议后续用 JS 初始化,避免初始 HTML 过重 -->
</div>
</nav>
</div>
</nav>步骤二:在主页面中预留占位符并注入
在每个需复用页眉的 .html 页面中(如 index.html),添加一个空容器,并在页面底部插入加载脚本:
立即学习“前端免费学习笔记(深入)”;
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Cate Cinema</title>
<link rel="stylesheet" href="../page_film/page_film.css">
<!-- 其他字体与图标 CSS(略) -->
</head>
<body id="homepage">
<!-- 占位符:页眉将被注入此处 -->
<div id="header-placeholder"></div>
<!-- 主要内容区域 -->
<main id="content">
<h1>Welcome to Cate Cinema</h1>
<!-- 页面具体内容 -->
</main>
<!-- 页脚同理可设 footer-placeholder -->
<div id="footer-placeholder"></div>
<!-- 加载脚本(推荐放在 body 底部,确保 DOM 已就绪) -->
<script>
// 确保 DOM 加载完成后再执行
document.addEventListener('DOMContentLoaded', () => {
fetch('../header/header.html')
.then(response => {
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.text();
})
.then(html => {
document.getElementById('header-placeholder').innerHTML = html;
// 可选:触发自定义事件,通知其他脚本(如导航初始化)
document.dispatchEvent(new CustomEvent('header-loaded'));
})
.catch(err => {
console.error('Failed to load header:', err);
// 可降级显示静态提示或错误占位内容
document.getElementById('header-placeholder').innerHTML =
'<div class="error-header">⚠️ Header failed to load</div>';
});
});
</script>
</body>
</html>⚠️ 注意事项与最佳实践
- 路径问题:fetch() 使用相对路径,务必确认 header.html 的实际路径与当前页面的相对关系(推荐统一存放于 /includes/ 目录下,并用 ./includes/header.html 调用)。
- SEO 与首屏性能:此方案为客户端渲染,搜索引擎爬虫可能无法索引注入内容;若 SEO 敏感,建议搭配服务端预渲染或使用构建工具(如 Eleventy、Hugo)。
- 样式与脚本隔离:header.html 中不应包含 <style> 或 <script> 标签——所有样式应集中于主 CSS 文件,交互逻辑(如下拉菜单)应在主页面 JS 中统一初始化。
- 错误处理必须添加:网络失败或 404 时提供降级方案(如静态提示),避免白屏。
- 页脚复用同理:只需复制相同逻辑,替换 id="footer-placeholder" 和对应 HTML 文件路径即可。
该方法简洁、标准、零依赖,完美适配纯静态部署场景,是中小型静态网站实现组件化复用的务实之选。


















