Prosemirror Editor DOMParser解析HTML丢失span标签问题求助
问题
尝试使用Prosemirror Editor的DOMParser解析HTML字符串:
const initialValue = '<p><span style="font-size:36px;"><span style="color:#00ff22;"><span style="background-color:#77b9c9;">hhkjhk hkjhkjh hjkhkj</span></span></span></p>' DOMParser.fromSchema(schema).parse(document.createRange().createContextualFragment(initialValue))
实际初始HTML结构:
<p> <span style="font-size:36px;"> <span style="background-color:#77b9c9;"> <span style="color:#00ff22;">world !!!</span> </span> </span> </p>
但解析后仅保留了最内层带颜色的span,其余带style的span都被移除:
<p> <span style="color:#00ff22;">world !!!</span> </p>
需要实现完整HTML解析,不丢失任何带样式的span标签,求对应的schema配置。
解决方案
ProseMirror默认schema不支持保留多层嵌套的span样式,需自定义schema,将字体大小、文字颜色、背景色定义为可叠加的标记(mark),并配置解析/序列化规则来识别对应的style属性。
完整自定义Schema配置
import { Schema } from 'prosemirror-model'; const customSchema = new Schema({ nodes: { // 根节点 doc: { content: "block+" }, // 段落节点,允许包含任意内联内容 paragraph: { content: "inline*", group: "block", parseDOM: [{ tag: "p" }], toDOM() { return ["p", 0]; } }, // 文本节点 text: { group: "inline" } }, marks: { // 文字颜色标记 color: { attrs: { color: { default: null } }, parseDOM: [{ style: "color", getAttrs: value => ({ color: value }) }], toDOM(mark) { return ["span", { style: `color: ${mark.attrs.color}` }, 0]; } }, // 背景色标记 backgroundColor: { attrs: { color: { default: null } }, parseDOM: [{ style: "background-color", getAttrs: value => ({ color: value }) }], toDOM(mark) { return ["span", { style: `background-color: ${mark.attrs.color}` }, 0]; } }, // 字体大小标记 fontSize: { attrs: { size: { default: null } }, parseDOM: [{ style: "font-size", getAttrs: value => ({ size: value }) }], toDOM(mark) { return ["span", { style: `font-size: ${mark.attrs.size}` }, 0]; } } } });
配置说明
- 节点定义:保留最基础的文档、段落、文本节点,确保结构解析的基础能力。
- 标记(mark)定义:每个样式属性对应一个mark:
parseDOM规则会从span的style属性中提取对应值,转换为mark的属性toDOM规则会将mark转换回带有对应style的span标签
- 叠加特性:ProseMirror的mark支持叠加应用,多层嵌套的span样式会被解析为多个mark绑定到文本节点上,序列化时会重新生成包含所有样式的结构(可能是嵌套span或单个span带多个style,样式信息完整保留)。
使用方式
用自定义schema解析HTML:
const initialValue = '<p><span style="font-size:36px;"><span style="background-color:#77b9c9;"><span style="color:#00ff22;">world !!!</span></span></span></p>'; const fragment = document.createRange().createContextualFragment(initialValue); const parsedDoc = DOMParser.fromSchema(customSchema).parse(fragment); // 验证解析结果:将文档转回HTML function docToHTML(doc, schema) { const serializer = require('prosemirror-model').DOMParser.fromSchema(schema).serialize; const div = document.createElement('div'); serializer(doc, { target: div }); return div.innerHTML; } console.log(docToHTML(parsedDoc, customSchema)); // 输出将包含所有样式的完整HTML结构
内容的提问来源于stack exchange,提问作者Abishek
相关产品推荐
相关产品推荐

