HTML标签闭合检查器

1. 输入 HTML 代码

2. 检查结果

常见问题与使用技巧

如何定位错误? 检查完成后,红色行号粉红背景 即为需闭合或修正的标签行。

支持哪些错误? 未闭合标签、标签嵌套错误、多余闭合标签。

支持大文件吗? 支持整页粘贴(>100 KB)秒级响应。

未闭合 span

错误嵌套:p 在 span 内

缺少 h2 闭合

`; function findUnclosedLines(html) { const tagRegex = /<\/?([a-zA-Z][a-zA-Z0-9-]*)\b[^>]*>/g; const selfClosing = new Set(['area','base','br','col','embed','hr','img','input','link','meta','param','source','track','wbr']); const stack = []; const unclosed = []; let match; while ((match = tagRegex.exec(html)) !== null) { const tag = match[0]; const tagName = match[1].toLowerCase(); const line = html.substring(0, match.index).split('\n').length; if (tag.startsWith('') && !selfClosing.has(tagName)) { stack.push({name: tagName, line}); } } return stack.map(item => ({name: item.name, line: item.line})); } function renderLines(list) { editor.eachLine(l => { editor.removeLineClass(l, 'background', 'cm-needClose'); editor.removeLineClass(l, 'gutter', 'cm-needClose'); }); if (!list.length) { $('#summary').html('✅ 全部标签已闭合'); return; } $('#summary').html(`${list.length} 处未闭合`); list.forEach(({line}) => { editor.addLineClass(line - 1, 'background', 'cm-needClose'); editor.addLineClass(line - 1, 'gutter', 'cm-needClose'); }); } $('#btnCheck').on('click', () => { const html = editor.getValue().trim(); if (!html) { layer.msg('请输入HTML'); return; } renderLines(findUnclosedLines(html)); }); $('#btnSample').on('click', () => { editor.setValue(sampleCode); renderLines(findUnclosedLines(sampleCode)); }); $('#btnClear').on('click', () => { editor.setValue(''); $('#summary').empty(); editor.eachLine(l => { editor.removeLineClass(l, 'background', 'cm-needClose'); editor.removeLineClass(l, 'gutter', 'cm-needClose'); }); }); });