From a4ddd3f48ecc0b69955c6088960f0582a89a6459 Mon Sep 17 00:00:00 2001 From: wonder Date: Mon, 24 Aug 2026 03:10:18 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20Mermaid=20=E6=94=BE=E5=A4=A7=E6=94=B9?= =?UTF-8?q?=E7=94=A8=E4=BA=8B=E4=BB=B6=E5=A7=94=E6=89=98=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/js/mermaid-zoom.js | 117 ++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/docs/js/mermaid-zoom.js b/docs/js/mermaid-zoom.js index 7564c04..f8a8943 100644 --- a/docs/js/mermaid-zoom.js +++ b/docs/js/mermaid-zoom.js @@ -1,67 +1,56 @@ -document.addEventListener('DOMContentLoaded', function () { - // 等待 Mermaid 渲染完成(Mermaid 在 DOMContentLoaded 之后异步渲染) - const observer = new MutationObserver(function () { - const svgs = document.querySelectorAll('.mermaid svg'); - if (svgs.length > 0) { - observer.disconnect(); - initMermaidZoom(); +// Mermaid 图表点击放大 — 事件委托方案 +;(function () { + // 创建 overlay + function openZoom(mermaidEl) { + var svg = mermaidEl.querySelector('svg'); + if (!svg) return; + + // 防止重复打开 + if (document.querySelector('.mermaid-zoom-overlay')) return; + + var clone = svg.cloneNode(true); + clone.removeAttribute('width'); + clone.removeAttribute('height'); + clone.style.width = 'auto'; + clone.style.height = 'auto'; + clone.style.maxWidth = '95vw'; + clone.style.maxHeight = '95vh'; + + var overlay = document.createElement('div'); + overlay.className = 'mermaid-zoom-overlay'; + overlay.appendChild(clone); + + overlay.addEventListener('click', function () { + overlay.classList.remove('active'); + setTimeout(function () { overlay.remove(); }, 200); + }); + + document.addEventListener('keydown', function handler(e) { + if (e.key === 'Escape') { + overlay.classList.remove('active'); + setTimeout(function () { overlay.remove(); }, 200); + document.removeEventListener('keydown', handler); + } + }); + + document.body.appendChild(overlay); + requestAnimationFrame(function () { + overlay.classList.add('active'); + }); + } + + // 事件委托:点击时往上找 .mermaid + document.addEventListener('click', function (e) { + var target = e.target.closest('.mermaid'); + if (target) { + e.preventDefault(); + e.stopPropagation(); + openZoom(target); } }); - observer.observe(document.body, { childList: true, subtree: true }); - - // 也尝试立即初始化(以防 Mermaid 已经渲染完) - setTimeout(initMermaidZoom, 1000); -}); - -function initMermaidZoom() { - // 避免重复绑定 - if (document.querySelector('.mermaid-zoom-overlay')) return; - - document.querySelectorAll('.mermaid').forEach(function (el) { - if (el.dataset.zoomBound) return; - el.dataset.zoomBound = 'true'; - - el.addEventListener('click', function () { - const svg = el.querySelector('svg'); - if (!svg) return; - - const clone = svg.cloneNode(true); - // 让克隆的 SVG 自适应放大 - clone.removeAttribute('width'); - clone.removeAttribute('height'); - clone.style.width = 'auto'; - clone.style.height = 'auto'; - clone.style.maxWidth = '95vw'; - clone.style.maxHeight = '95vh'; - - const overlay = document.createElement('div'); - overlay.className = 'mermaid-zoom-overlay'; - overlay.appendChild(clone); - - // 点击 overlay 关闭 - overlay.addEventListener('click', function (e) { - if (e.target === overlay || e.target.closest('svg')) { - overlay.classList.remove('active'); - setTimeout(function () { overlay.remove(); }, 200); - } - }); - - // ESC 关闭 - function onKey(e) { - if (e.key === 'Escape') { - overlay.classList.remove('active'); - setTimeout(function () { overlay.remove(); }, 200); - document.removeEventListener('keydown', onKey); - } - } - document.addEventListener('keydown', onKey); - - document.body.appendChild(overlay); - // 触发动画 - requestAnimationFrame(function () { - overlay.classList.add('active'); - }); - }); - }); -} + // 兼容 MkDocs Material instant navigation: + // 页面切换后 Mermaid 可能重新渲染,无需重新绑定(事件委托天然兼容) + // 但需要确保 .mermaid 的 cursor 样式对新渲染的图表也生效 + // (CSS 全局生效,无需额外处理) +})();