fix: 修复共性需求说明文档预览的目录联动和表格框线问题
- 为标题补充锚点id解决marked新版不自动生成id导致目录跳转失效 - 向iframe注入表格框线及排版样式 - 添加滚动监听实现目录高亮联动 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+40
-6
@@ -78,25 +78,59 @@ if (filePath) {
|
||||
/* 检测是否为自带 HTML 结构的文件(如共性需求说明.md) */
|
||||
const isRawHtml = /^\s*<(?:style|div|!doctype|html)/i.test(md);
|
||||
if (isRawHtml) {
|
||||
/* 文件混合了 HTML 结构和 Markdown 内容,需先解析 Markdown 再渲染 */
|
||||
/* 为标题生成锚点 id(marked 新版不再自动生成) */
|
||||
function addHeadingIds(html) {
|
||||
return html.replace(/<h([1-6])>([\s\S]*?)<\/h\1>/g, function(_, lvl, inner) {
|
||||
var plain = inner.replace(/<[^>]*>/g, '');
|
||||
var id = plain.toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, '').trim().replace(/\s+/g, '-');
|
||||
return '<h' + lvl + ' id="' + id + '">' + inner + '</h' + lvl + '>';
|
||||
});
|
||||
}
|
||||
let processed = md;
|
||||
if (typeof marked !== 'undefined') {
|
||||
/* 保留 <style>/<div> 等 HTML 标签,只对标签外的 Markdown 文本做解析 */
|
||||
processed = md.replace(/(^[\s\S]*?<div id="main-content">)([\s\S]*?)(<\/div>\s*$)/i, function(_, before, mdBody, after) {
|
||||
return before + marked.parse(mdBody) + after;
|
||||
return before + addHeadingIds(marked.parse(mdBody)) + after;
|
||||
});
|
||||
/* 同时解析 toc-container 内的 Markdown 列表 */
|
||||
processed = processed.replace(/(<div id="toc-container">)([\s\S]*?)(<\/div>)/, function(_, before, tocBody, after) {
|
||||
return before + marked.parse(tocBody) + after;
|
||||
});
|
||||
}
|
||||
/* 用 iframe 隔离渲染,避免宿主页样式冲突 */
|
||||
/* iframe 内注入:表格框线 + 排版样式 */
|
||||
const extraCss = '<style>'
|
||||
+ 'html{scroll-behavior:smooth}'
|
||||
+ 'body{font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Helvetica Neue","Segoe UI",sans-serif}'
|
||||
+ '#main-content table{width:100%;border-collapse:collapse;margin:12px 0;font-size:14px}'
|
||||
+ '#main-content th{background:#fafafa;font-weight:600;text-align:left;padding:8px 12px;border:1px solid #e8ecf1}'
|
||||
+ '#main-content td{padding:8px 12px;border:1px solid #e8ecf1}'
|
||||
+ '#main-content h1{font-size:24px;font-weight:800;margin:0 0 16px;padding-bottom:10px;border-bottom:2px solid #e8ecf1}'
|
||||
+ '#main-content h2{font-size:20px;font-weight:700;margin:32px 0 12px;padding-bottom:8px;border-bottom:1px solid #e8ecf1}'
|
||||
+ '#main-content h3{font-size:17px;font-weight:600;margin:24px 0 8px}'
|
||||
+ '#main-content h4{font-size:15px;font-weight:600;margin:20px 0 6px}'
|
||||
+ '#main-content p{font-size:14px;line-height:1.8;margin:8px 0}'
|
||||
+ '#main-content ul,#main-content ol{padding-left:20px;margin:8px 0;font-size:14px;line-height:1.8}'
|
||||
+ '#main-content code{background:#f5f5f5;padding:2px 6px;border-radius:4px;font-size:13px}'
|
||||
+ '#main-content blockquote{border-left:4px solid #1677FF;padding:8px 16px;margin:12px 0;background:#E6F7FF;border-radius:0 4px 4px 0}'
|
||||
+ '#toc-container a.active{color:#1677FF;font-weight:600}'
|
||||
+ '</style>';
|
||||
/* iframe 内注入:滚动时高亮当前目录项 */
|
||||
const tocScript = '<script>'
|
||||
+ 'document.addEventListener("DOMContentLoaded",function(){'
|
||||
+ 'var links=document.querySelectorAll("#toc-container a[href^=\\"#\\"]");'
|
||||
+ 'var items=[];'
|
||||
+ 'links.forEach(function(a){var id=decodeURIComponent(a.getAttribute("href").slice(1));var el=document.getElementById(id);if(el)items.push({el:el,link:a})});'
|
||||
+ 'if(!items.length)return;'
|
||||
+ 'function update(){var sy=window.scrollY||document.documentElement.scrollTop;var cur=items[0];'
|
||||
+ 'for(var i=0;i<items.length;i++){if(items[i].el.offsetTop<=sy+80)cur=items[i]}'
|
||||
+ 'links.forEach(function(a){a.classList.remove("active")});if(cur)cur.link.classList.add("active")}'
|
||||
+ 'window.addEventListener("scroll",update);update()});'
|
||||
+ '<\/script>';
|
||||
/* 用 iframe 隔离渲染 */
|
||||
document.querySelector('.topbar').style.display = 'none';
|
||||
const wrap = document.getElementById('content');
|
||||
wrap.style.cssText = 'max-width:none;margin:0;padding:0;min-height:100vh';
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.cssText = 'width:100%;height:100vh;border:none';
|
||||
iframe.srcdoc = '<!DOCTYPE html><html><head><meta charset="UTF-8"></head><body>' + processed + '</body></html>';
|
||||
iframe.srcdoc = '<!DOCTYPE html><html><head><meta charset="UTF-8">' + extraCss + '</head><body>' + processed + tocScript + '</body></html>';
|
||||
wrap.innerHTML = '';
|
||||
wrap.appendChild(iframe);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user