用data-module替代class/id锚定模块可解决js查询失效、样式错位等问题,因其不参与样式、不影响可访问性、不随视觉重命名变更;需配合语义标签和实现高可维护性。

用 data-module 替代 class/id 锚定功能模块
JS 查询失效、样式错位、改一个 class 全站崩——根本原因不是代码写得慢,而是锚点不稳定。data-module 是专为模块边界设计的属性,不参与样式、不影响可访问性,也不随视觉重命名而变。
常见错误现象:$('.header-nav') 在新设计中 class 改成 top-bar-menu,脚本静默失败;document.getElementById('product-list') 在循环渲染时只取到第一个节点。
- 每个独立功能区块加根级
data-module="header"、data-module="product-grid",版本号可同步加data-version="2.3" - JS 统一用
document.querySelectorAll('[data-module="header"]')查询,CI 流程可校验版本是否匹配文档 - 禁止在
data-module值里塞动态内容(如data-module="product-{{id}}"),它代表抽象模块类型,不是实例标识 - 嵌套超三层必须重构——不是警告,是红线。Chrome DevTools 中右键节点 → “Break on” → “Attribute modifications”,能快速暴露冗余包裹层
语义化标签不是加分项,是 DOM 接口契约
把 <div class="nav"> 换成 <code><nav></nav> 不是为了“更规范”,而是为了让浏览器同时构建出无障碍树(Accessibility Tree)。没有它,屏幕阅读器、爬虫、自动化测试工具都只能靠猜。
使用场景:SEO 提升、辅助设备适配、自动化测试定位、团队协作时无需注释解释“这个 div 是导航”。
-
<header></header>、<nav></nav>、<main></main>、<section></section>、<aside></aside>、<footer></footer>必须成对出现,且<main></main>应唯一 - 避免
<div class="header"> 这类无语义包裹;两个连续 <code><section></section>若主题相同,不如合并并用<h2></h2>分隔子区块 -
<article></article>用于可独立分发的内容(如博客、新闻);<section></section>用于逻辑分组,不可替代<article></article> - 标题层级必须严格:从
<h1></h1>开始,<h2></h2>是<section></section>的首级标题,禁止跳级或用<h3></h3>当首标 - 构建时静态加载推荐 Vite 的
import headerHtml from './header.html?raw',Webpack 配html-loader - 运行时
fetch加载后,若片段含<script></script>,需手动创建并插入,否则逻辑断链 -
<img src="logo.png">在fetch返回的字符串中会 404,除非已设<base href="/>%20%E6%88%96%E8%B7%AF%E5%BE%84%E5%86%99%E6%88%90%E7%BB%9D%E5%AF%B9 %0A - %E7%A6%81%E7%94%A8%20
innerHTML%20+=%20%E6%8B%BC%E6%8E%A5%EF%BC%8C%E6%AF%8F%E6%AC%A1%E9%83%BD%E4%BC%9A%E9%87%8D%E6%96%B0%E8%A7%A3%E6%9E%90%E6%95%B4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E4%B8%94%E4%B8%A2%E5%A4%B1%E5%B7%B2%E6%9C%89%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC%E5%99%A8 %0A - %E6%A0%B9%E7%9B%AE%E5%BD%95%E5%8F%AA%E6%94%BE%20
index.html%EF%BC%9Bcss/%E3%80%81js/%E3%80%81images/%E3%80%81pages/%20%E5%9B%9B%E4%B8%AA%E6%A0%87%E5%87%86%E7%9B%AE%E5%BD%95%E5%BF%85%E9%A1%BB%E5%AD%98%E5%9C%A8 %0A images/%20%E4%B8%8B%E6%8C%89%E7%94%A8%E9%80%94%E5%86%8D%E5%BB%BA%E5%AD%90%E7%9B%AE%E5%BD%95%EF%BC%88%E5%A6%82%20icons/%E3%80%81banner/%EF%BC%89%EF%BC%8C%E9%81%BF%E5%85%8D%E6%89%80%E6%9C%89%E5%9B%BE%E6%8C%A4%E5%9C%A8%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E5%A4%B9 %0A- %E5%A4%9A%E9%A1%B5%E9%9D%A2%E7%BB%9F%E4%B8%80%E5%AF%BC%E8%88%AA%E6%8E%A8%E8%8D%90%E5%89%8D%E7%AB%AF%E5%8A%A8%E6%80%81%E6%B3%A8%E5%85%A5%EF%BC%9A%E7%94%A8%20
nav-loader.js%20%E5%AE%9A%E4%B9%89%20const%20navHTML%20=%20%60<nav>...</nav>%60%EF%BC%8C%E8%80%8C%E9%9D%9E%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8C%85%E5%90%AB%E6%88%96%E9%87%8D%E5%A4%8D%E5%86%99%20HTML %0A partials/%20%E5%AD%98%E6%94%BE%E6%A8%A1%E5%9D%97%E5%8C%96%20HTML%20%E7%89%87%E6%AE%B5%EF%BC%88%E5%A6%82%20header.html%E3%80%81footer.html%EF%BC%89%EF%BC%8C%E9%85%8D%E5%90%88%20<template>%20+%20fetch%20%E5%8A%A0%E8%BD%BD%EF%BC%8C%E7%A1%AE%E4%BF%9D%E5%A4%8D%E7%94%A8%E4%B8%8E%E9%9A%94%E7%A6%BB %0A
<template></template> 是 HTML 片段的唯一合法容器
把页头 HTML 写在 <div style="display:none"> 里,或拼字符串插入 <code>innerHTML,短期省事,长期必踩坑:样式未加载、脚本不执行、相对路径 404、无 DOM 生命周期控制。
性能影响:内联字符串会触发多次解析与重排;<template></template> 不渲染、不计算样式、不触发资源加载,JS 克隆后插入才是干净起点。
%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84%E5%92%8C%E6%96%87%E4%BB%B6%E7%BB%84%E7%BB%87%E5%86%B3%E5%AE%9A%E5%90%8E%E6%9C%9F%E6%94%B9%E7%89%88%E6%88%90%E6%9C%AC
%0A%E4%B8%80%E4%B8%AA%E6%B2%A1%E8%A7%84%E5%88%92%E7%9A%84%20index.html%20%E5%92%8C%E4%B8%80%E5%A0%86%E6%95%A3%E8%90%BD%E5%9C%A8%E6%A0%B9%E7%9B%AE%E5%BD%95%E7%9A%84%20JS/CSS%EF%BC%8C%E7%AD%89%E4%BA%8E%E7%BB%99%E6%AF%8F%E6%AC%A1%E6%94%B9%E7%89%88%E5%9F%8B%E9%9B%B7%E3%80%82%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84%E4%B8%8D%E6%98%AF%E4%B8%BA%E4%BA%86%E6%95%B4%E9%BD%90%EF%BC%8C%E6%98%AF%E4%B8%BA%E4%BA%86%E8%AE%A9%E2%80%9C%E6%94%B9%E5%93%AA%E9%87%8C%E3%80%81%E5%8A%A8%E4%BB%80%E4%B9%88%E3%80%81%E5%BD%B1%E5%93%8D%E8%B0%81%E2%80%9D%E4%B8%80%E7%9B%AE%E4%BA%86%E7%84%B6%E3%80%82
%E5%AE%B9%E6%98%93%E8%B8%A9%E7%9A%84%E5%9D%91%EF%BC%9A%E5%9B%BE%E7%89%87%E8%B7%AF%E5%BE%84%E5%86%99%E6%AD%BB%E3%80%81CSS%20%E5%BC%95%E5%85%A5%E9%A1%BA%E5%BA%8F%E6%B7%B7%E4%B9%B1%E5%AF%BC%E8%87%B4%E8%A6%86%E7%9B%96%E5%A4%B1%E6%95%88%E3%80%81%E5%A4%9A%E9%A1%B5%E9%9D%A2%E5%AF%BC%E8%88%AA%E9%80%90%E9%A1%B5%E5%A4%8D%E5%88%B6%E7%B2%98%E8%B4%B4%E3%80%82
%0A- %0A
data-module%20%E5%B0%B1%E4%BC%9A%E9%80%80%E5%8C%96%E6%88%90%E5%8F%A6%E4%B8%80%E4%B8%AA%20class%EF%BC%8C%E8%AF%AD%E4%B9%89%E6%A0%87%E7%AD%BE%E4%BC%9A%E8%A2%AB%E5%BD%93%E6%88%90%E2%80%9C%E5%8F%AF%E6%9C%89%E5%8F%AF%E6%97%A0%E7%9A%84%E8%A3%85%E9%A5%B0%E2%80%9D%EF%BC%8C<template>%20%E4%BC%9A%E8%A2%AB%E7%BB%95%E5%BC%80%E7%9B%B4%E5%A5%94%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8B%BC%E6%8E%A5%E2%80%94%E2%80%94%E8%BF%99%E4%BA%9B%E4%B8%8D%E6%98%AF%E6%8A%80%E6%9C%AF%E9%80%89%E6%8B%A9%E9%97%AE%E9%A2%98%EF%BC%8C%E8%80%8C%E6%98%AF%E5%8D%8F%E4%BD%9C%E5%A5%91%E7%BA%A6%E6%98%AF%E5%90%A6%E8%A2%AB%E7%9C%9F%E6%AD%A3%E6%89%A7%E8%A1%8C%E7%9A%84%E9%97%AE%E9%A2%98%E3%80%82%0A">











