html如何将几个网页共用一个头

2次阅读

最推荐构建阶段处理,如用11ty将header抽为_includes/header.njk并用{% include ‘header.njk’ %}注入,生成纯静态html;若只能用客户端方案,需domcontentloaded后fetch加载并手动初始化交互,注意资源路径和csp限制。

html如何将几个网页共用一个头

HTML 中怎么复用同一个 <header></header>

不能直接在多个 HTML 文件里写死同一段 header 代码,否则改一次得同步改几十个文件。最简单靠谱的做法是服务端包含(SSI)或构建时处理,但如果你只有纯静态页面、没服务器权限,就得靠客户端方案兜底。

  • fetch() + innerHTML 动态加载:适合现代浏览器,但 seo 不友好,首屏有白屏延迟
  • <iframe></iframe> 嵌入:兼容性最好,但样式隔离、高度自适应、SEO 同样差,还可能被 CSP 拦截
  • 真正推荐的是构建阶段处理:用 html-webpack-plugin(Webpack)、eleventy(11ty)或甚至 shell 脚本把公共 header.html 注入到每个页面中——生成的是纯静态 HTML,无运行时依赖

用 JavaScript 动态插入 header 的典型写法

不是所有项目都能上构建工具,临时方案就得靠 js。关键不是“能不能加”,而是“加完样式和交互是否正常”。

  • 必须等 DOMContentLoaded 触发后再操作 DOM,否则 document.querySelector('header') 找不到目标位置
  • 插入后记得手动初始化 header 里的 JS 行为,比如导航菜单的点击事件——动态插入的元素不会自动绑定原有事件监听器
  • 如果 header 含 <link rel="stylesheet"><script></script>,要确保路径是相对当前 HTML 的,不是相对于被加载的 header.html 文件
  • 示例:
    fetch('components/header.html')<br>  .then(r => r.text())<br>  .then(html => {<br>    document.getElementById('header-placeholder').innerHTML = html;<br>    initHeaderNav(); // 手动触发初始化<br>  });

为什么 <include></include>@include 在原生 HTML 里不生效

因为浏览器根本不认识这些语法——它们是 SSI、PHP、Jinja、EJS 等服务端或模板引擎的指令,不是 HTML 标准。直接写进 .html 文件,浏览器会当普通文本渲染,甚至可能报解析错误。

  • <!--#include file="header.html"--> 只在启用 SSI 的 apache/nginx 上有效,且需配置 Includes 选项
  • 是 EJS 语法,必须经 EJS 引擎编译,不能直接双击打开 .html
  • 本地用 file:// 协议打开时,fetch() 会因跨域限制失败(CORS),必须起一个本地服务,比如 npx servepython3 -m http.server

构建时复用 header 的最小可行配置(以 11ty 为例)

比手写 JS 更稳,比配 Webpack 更轻量。核心是把 header 抽成单独文件,用模板语法引用。

立即学习前端免费学习笔记(深入)”;

  • 把公共头存为 _includes/header.njk(Nunjucks 格式)或 _includes/header.liquid
  • 在页面模板里写 {% include 'header.njk' %},11ty 构建时自动合并
  • 支持传参:比如 {% include 'header.njk' navItems=navItems %},让 header 根据页面动态变化
  • 注意路径:11ty 默认只处理 _includes_data 目录,放错位置不会报错,但内容不会出现

实际项目里最容易被忽略的点是 header 中的相对路径资源(比如 logo.pngmain.css)。它们在独立文件里看着正常,一旦被注入到不同层级的页面(如 /about/index.html vs /index.html),路径就全乱了。统一用根对齐路径(/assets/logo.png)或者构建时用 posthtml 插件重写,别指望浏览器自动猜。

text=ZqhQzanResources