From 89375a6e0f296a3963e5450e6664dddc9b4512da Mon Sep 17 00:00:00 2001 From: LooseLi <1329307562@qq.com> Date: Wed, 4 Jun 2025 12:02:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20spoiler=E6=97=A0=E6=B3=95=E9=9A=90?= =?UTF-8?q?=E8=97=8F=E5=A4=8D=E6=9D=82=E6=96=87=E6=9C=AC=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/js/spoilerText.js | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/public/js/spoilerText.js b/public/js/spoilerText.js index c0b12895..2d9c7104 100644 --- a/public/js/spoilerText.js +++ b/public/js/spoilerText.js @@ -1,3 +1,12 @@ +/** + * 转义正则表达式中的特殊字符 + * @param {string} string 需要转义的字符串 + * @returns {string} 转义后的字符串 + */ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') +} + /** * 将Node文本中的指定标签内容转换为带有指定类名的span * @param regex @@ -61,6 +70,47 @@ function processTextNodes(root, className, spoilerTag) { for (const waitProcessNode of waitProcessNodes) { convertTextToSpoilerSpan(regex, waitProcessNode, className) } + + // 处理跨节点的 spoiler 标记 + processCrossNodeSpoilers(root, className, spoilerTag) +} + +/** + * 处理跨节点的 spoiler 标记 + * @param {Element} root 要处理的根元素 + * @param {string} className 应用于 spoiler 内容的类名 + * @param {string} spoilerTag spoiler 标记符号 + */ +function processCrossNodeSpoilers(root, className, spoilerTag) { + if (root.nodeType !== Node.ELEMENT_NODE) return + + const html = root.innerHTML + + // 处理原始标签,如果是已经转义过的,则去除转义 + let originalTag = spoilerTag + if (spoilerTag.startsWith('\\') || spoilerTag.includes('\\[')) { + originalTag = spoilerTag.replace(/\\/g, '') + } + + // 创建正则表达式,直接匹配原始标签 + const regex = new RegExp(`\\${originalTag}([\\s\\S]*?)\\${originalTag}`, 'g') + + const hasMatch = regex.test(html) + + if (!hasMatch) return + + // 重置正则表达式 + regex.lastIndex = 0 + + // 替换匹配项 + const newHtml = html.replace(regex, function (match, content) { + return `${content}` + }) + + // 如果内容有变化,更新 DOM + if (newHtml !== html) { + root.innerHTML = newHtml + } } /**