将quill-mention生成的HTML Span转换为@data-id格式并支持还原
1. Quill-Mention HTML 转 @data-id 格式
通过解析HTML DOM定位所有带mention类的<span>标签,将其替换为@<data-id>格式,同时保留原有HTML结构:
function convertMentionHtmlToIdFormat(htmlStr) { const parser = new DOMParser(); const doc = parser.parseFromString(htmlStr, 'text/html'); const mentionSpans = doc.querySelectorAll('span.mention'); mentionSpans.forEach(span => { const dataId = span.getAttribute('data-id'); if (dataId) { const textNode = document.createTextNode(`@${dataId}`); span.parentNode.replaceChild(textNode, span); } }); return doc.body.innerHTML; } // 示例调用 const originalHtml = '<p>Hi <span class="mention" data-index="0" data-denotation-char="@" data-id="58963f62-3417-481f-9d46-4f5625e9a1ab" data-value="test1 "><span contenteditable="false"><span class="ql-mention-denotation-char">@</span>test1 </span></span> Hi <span class="mention" data-index="0" data-denotation-char="@" data-id="58963f62-3417-481f-9d46-4f5625e9a1cd" data-value="test2 "><span contenteditable="false"><span class="ql-mention-denotation-char">@</span>test2 </span></span> </p>'; const convertedText = convertMentionHtmlToIdFormat(originalHtml); console.log(convertedText); // 输出: <p>Hi @58963f62-3417-481f-9d46-4f5625e9a1ab Hi @58963f62-3417-481f-9d46-4f5625e9a1cd </p>
2. @data-id 格式还原为 Quill-Mention HTML
还原时需匹配文本中的@<UUID>格式内容,替换为Quill-Mention标准<span>结构,需提前准备id到用户信息的映射表:
function convertIdFormatToMentionHtml(convertedStr, userMap) { const parser = new DOMParser(); const doc = parser.parseFromString(convertedStr, 'text/html'); function traverseNodes(node) { if (node.nodeType === Node.TEXT_NODE) { const text = node.textContent; const regex = /@([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})/g; let match; const fragments = []; let lastIndex = 0; while ((match = regex.exec(text)) !== null) { if (match.index > lastIndex) { fragments.push(document.createTextNode(text.slice(lastIndex, match.index))); } const userId = match[1]; const userInfo = userMap[userId]; if (userInfo) { const mentionSpan = document.createElement('span'); mentionSpan.className = 'mention'; mentionSpan.setAttribute('data-index', '0'); mentionSpan.setAttribute('data-denotation-char', userInfo.denotationChar || '@'); mentionSpan.setAttribute('data-id', userId); mentionSpan.setAttribute('data-value', userInfo.value); const contentSpan = document.createElement('span'); contentSpan.setAttribute('contenteditable', 'false'); const denotationSpan = document.createElement('span'); denotationSpan.className = 'ql-mention-denotation-char'; denotationSpan.textContent = userInfo.denotationChar || '@'; contentSpan.appendChild(denotationSpan); contentSpan.appendChild(document.createTextNode(userInfo.displayName)); mentionSpan.appendChild(contentSpan); fragments.push(mentionSpan); } else { fragments.push(document.createTextNode(match[0])); } lastIndex = regex.lastIndex; } if (lastIndex < text.length) { fragments.push(document.createTextNode(text.slice(lastIndex))); } if (fragments.length > 0) { const parent = node.parentNode; fragments.forEach(frag => parent.insertBefore(frag, node)); parent.removeChild(node); } } else if (node.nodeType === Node.ELEMENT_NODE) { Array.from(node.childNodes).forEach(traverseNodes); } } traverseNodes(doc.body); return doc.body.innerHTML; } // 示例调用 const userMap = { '58963f62-3417-481f-9d46-4f5625e9a1ab': { value: 'test1 ', displayName: 'test1 ', denotationChar: '@' }, '58963f62-3417-481f-9d46-4f5625e9a1cd': { value: 'test2 ', displayName: 'test2 ', denotationChar: '@' } }; const restoredHtml = convertIdFormatToMentionHtml(convertedText, userMap); console.log(restoredHtml); // 输出与原始HTML结构一致
内容的提问来源于stack exchange,提问作者Sahil
相关产品推荐
相关产品推荐

