htmlhint 默认不检测非法嵌套(如 ),需通过自定义规则监听 tagstart 事件并结合 parser.currentparent() 判断父-子标签合法性,且须正确配置 rulesdir 和过滤模板语法。

如何让 HTMLHint 检测非法嵌套(比如
里放
HTMLHint 默认不检查语义嵌套合法性,tag-pair 只管开闭匹配,不管 <p></p>
<div></div>
attr-validate + 自定义规则,或借助 id-class-ad-disabled 等间接约束手段。实操建议:
-
tag-pair能发现漏闭合、交叉闭合(如<div><p></p></div>),但对合法标签内的非法子元素完全沉默 - 浏览器 DevTools Elements 面板会把
<p></p> <div></div>渲染成<p></p> <div></div>并灰显,这是最直接的视觉线索 - W3C Validator 能报出
Element div not allowed as child of element p,但无法集成进编辑器实时反馈 - 若需在保存时拦截,得写自定义规则监听
tagstart事件,判断父节点是否在白名单内(例如p的合法子元素不含div)
自定义规则中怎么判断父-子标签是否允许嵌套
HTMLHint 的 init 函数里通过 parser 监听事件获取上下文,关键不是“当前标签是什么”,而是“它当前被谁包裹”。
示例逻辑(检查 <div> 是否在 <code><p></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9263" title="Html2md"><img
src="https://img.php.cn/upload/skill/000/000/081/179249945220127.jpg" alt="Html2md" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="overflowclass">Html2md</a>
<p class="overflowclass">使用 Readability + Turndown 将 HTML 页面转换为干净的、Agent 友好的 Markdown。去除导航栏、广告、页脚、Cookie 横幅、社交按钮等干扰元素。支持 URL...</p>
</div>
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div> 内):
parser.addListener('tagstart', (event) => {
if (event.tag === 'div' && parser.currentParent() === 'p') {
reporter.error('div cannot be child of p', event.line, event.col, this);
}
});
注意点:
-
parser.currentParent()返回最近的开放父标签名(大小写敏感,需用toLowerCase()统一) - 不能依赖
event.parent——该字段不存在;必须靠解析器内部状态 - 若项目含 Vue/JSX 片段,
parser可能误判模板语法为标签,需加if (!event.raw.includes('{{') && !event.raw.includes('v-'))过滤 - 规则 ID 如
no-div-in-p必须全小写,否则.htmlhintrc中启用失败
为什么 .htmlhintrc 放错位置会导致自定义规则不生效
HTMLHint 查找配置文件只向上扫描一级目录,且仅认 .htmlhintrc(带点开头)或 htmlhint.conf.js。如果自定义规则放在 rules/ 子目录,而 .htmlhintrc 在根目录却没引用它,规则根本不会加载。
正确做法:
- 自定义规则文件(如
rules/no-div-in-p.js)需在.htmlhintrc中通过"rulesdir"显式声明:"rulesdir": ["./rules"] -
rulesdir路径是相对于.htmlhintrc所在位置,不是相对于执行命令的路径 - VS Code 插件默认只读取工作区根目录的
.htmlhintrc,打开子文件夹作为工作区时,插件可能找不到配置 - 命令行运行
npx htmlhint --config src/.htmlhintrc src/**/*.html时,rulesdir路径仍以src/.htmlhintrc为基准,不是项目根
自定义嵌套规则上线前必须验证的三个边界场景
写完规则别急着合入,先用这三类 HTML 片段手动触发测试:
- 含注释的嵌套:
<p><!-- comment --></p> <div></div>—— 注释不应影响父级判定 - 自闭合标签干扰:
<p><img src=""></p> <div></div>——<img>不应改变currentParent()值 - 动态属性干扰:
<p v-if="show"></p> <div></div>—— 若未过滤 Vue 指令,会误报
真正难的是处理 <template></template> 块和 SSR 渲染片段——它们结构合法但语义模糊,规则要么放宽条件,要么交由框架专用 linter 处理。










